c++ - 如何选择通用模板和函数重载?
问题描述
我最初试图为std::vector
. 我有一个模板化的构造函数,它转发一个参数包来模仿不同的构造函数std::vector
。std::vector
然后,如果 a被传入,我决定有一些专门/重载的。
在编写它时,我决定尝试不同的函数重载和模板专业化如何工作。
这是我拥有的代码:
template<typename Type>
struct myVec
{
template <typename ...Params>
myVec(Params&&... params)
:vec(std::forward<Params>(params)...)
{
std::cout << "Generic used\n";
}
template <>
myVec<std::vector<Type>&&>(std::vector<Type>&& params)
{
std::cout << "Specialization used\n";
}
myVec(std::vector<Type>& params)
{
std::cout << "Overload used\n";
}
private:
std::vector<Type> vec;
};
int main()
{
std::vector<int> v{1,2,3,4,5};
myVec<int> vec1(v); // Print "Overload Used"
myVec<int> vec2(std::vector<int> {1,2,3,4,5}); // Print "Specialization used"
// myVec<int> vec3(&v); // Error, attempting to use generic template,
// which attempt to search for std::vector(std::vector& vec), which does not exist
}
所以我的问题是他们究竟如何决定使用哪些构造函数?我以为vec1
会使用通用模板,并vec3
会使用重载,但显然情况并非如此。
似乎对于我的专业来说,我可以将显式模板替换<std::vector<Type>&&>
为<std::vector<Type>>
to <>
,或者将其全部删除,它们对我来说都一样吗?
解决方案
首先,您的代码无法在 GCC 上编译(我猜您正在使用 VS?)这是因为如果不专门化整个类,就无法专门化 myVec 构造函数的模板。请参阅: 非命名空间范围内的显式专业化
正如您在问题的最后一段中所说,无论如何都不需要专业化,因此您可以将其删除。此代码有效:
#include <iostream>
#include <vector>
template<typename Type>
struct myVec
{
template <typename ...Params>
myVec(Params&&... params)
:vec(std::forward<Params>(params)...)
{
std::cout << "Generic used\n";
}
myVec(std::vector<Type>&& params)
{
std::cout << "Specialization used\n";
}
myVec(std::vector<Type>& params)
{
std::cout << "Overload used\n";
}
private:
std::vector<Type> vec;
};
int main()
{
std::vector<int> v{1,2,3,4,5};
myVec<int> vec1(v); // Print "Overload Used"
myVec<int> vec2(std::vector<int> {1,2,3,4,5}); // Print "Specialization used"
// myVec<int> vec3(&v); // Error, attempting to use generic template,
// which attempt to search for std::vector(std::vector& vec), which does not exist
}
vec1 使用重载模板,因为,嗯....它是直接匹配的。没有其他构造函数与参数匹配v
。这是因为当您将 v 传递给构造函数时,它将作为左值引用传递,即std::vector<int>&
(或const vector<int>&
)。请参阅左值参考:
https://en.cppreference.com/w/cpp/language/reference
vec2 使用 'specialized' 模板,因为它需要一个右值引用并将std::vector<int>{1, 2, 3, 4, 5}
作为右值引用传递。所以这是一个精确的匹配。
推荐阅读
- html - 如何强制将 br 分隔的链接列表显示为项目符号列表?
- html - How can I display html image in a container the same way css displays background-image?
- python - 从页面获取脚本标签的内容并使用 python 将其保存为 javascript 文件格式
- keycloak - 使用 keycloak rest api 更新用户的问题
- android - 深度链接在 Chrome 移动浏览器中不起作用
- oracle - GRANT SELECT ON view TO user using script on SQL developer, 而不是 SELECT * FROM SQL Plus 中的那个视图
- java - Android:如何将 ImageView 保存到 SharedPreferences 以进行保存和检索?
- sql - 是否可以在 SUM 函数中使用 COALESCE 函数?
- arrays - 制作宾果游戏:如何检查数组中的元素是否重复并更改其值而不再次与其他元素重复
- excel - VBS 脚本无法将文件上传到共享点