提问人:anurag86 提问时间:2/4/2020 最后编辑:anurag86 更新时间:2/4/2020 访问量:307
“专业化不参与超载”
"specializations don’t participate in overloading"
问:
“函数模板的专业化”的真正含义是什么 不要参与过载解决。仅考虑基本模板”
我用它的专用版本编写了一个简单的模板函数,可以看到它调用了specialized:
// Base template
template <typename T>
T max(T a, T b) {
std::cout << "Base Template" << std::endl;
return (a>b) ? a : b;
}
// Specialization for int
template<>
int max<int>(int a, int b) {
std::cout << "int specialization" << std::endl;
return (a>b) ? a : b;
}
max(2,3);// prints "int specialization"
查看与此概念相关的其他 StackOverflow,我发现了另一篇文章,其中证明专业化不参与重载,他展示了以下示例,其中没有调用专用版本,我仍然不确定为什么没有调用它。但除此之外,在此示例中,参数没有变量名称,但该部分仍然没有编译或运行时错误(char const* const&)
template<typename T>
void f(T const&)
{
std::cout<<std::endl<<"Base Template for f() called\n";
}
template<>
void f<char const * const &>(char const* const&)
{
std::cout<<std::endl<<"Specialized f() for char const* called\n";
}
f("Hello") //prints "Base Template for f() called"
总而言之,我仍在试图弄清楚“函数模板的专业化不要参与过载解决”的含义。只考虑基本模板“,如果有人可以用一个例子来解释(以及为什么在第二个例子中调用基本模板)。 其次,为什么程序在第二个示例中没有变量名的情况下编译并运行良好。
答:
5赞
Sneaky Turtle
2/4/2020
#1
如果尝试,即使 a 可转换为 .因此,专业化不参与过载解决。max(5, 7.0)
double
int
int
max
template <typename T>
T max(T a, T b);
template <>
int max(int a, int b);
max(5, 7.0); // compiler error (no matching function)
但是,如果您使用常规函数而不是模板专用化,则将获得预期的行为。
template <typename T>
T max(T a, T b);
int max(int a, int b);
max(5, 7.0); // this is fine
当编译器考虑参数类型时,它会按以下顺序查找函数(ADL和其他细节比这更复杂):(int, double)
- 完全匹配的函数(例如.所以现阶段不会考虑)
max(int, double)
max(int, int)
- 匹配函数模板(例如.所以不会被考虑,因为不能同时是和
max(T, U)
max(T, T)
T
int
double
) - 具有兼容参数的函数(例如 since 隐式转换为
max(int, int)
double
int
)
请注意,我没有提到函数模板专用化。如果找到匹配的函数模板,则将使用完全匹配的专用化(因此,如果您专门用于 s,但您调用了 s,则不会使用该专用化),否则将使用基本模板。double
int
有关更好的解释,请参阅 cppreference。
评论
0赞
anurag86
2/4/2020
同意。但是,混乱不止于此,这就是我提供第二个示例的原因。在这种情况下,将专用版本称为 不合适吗?您可以尝试使用specialized,您将始终看到specialized被调用。现在只需将 更改为,您将看到 Base 模板而不是 specialized 被调用。不知道为什么char const * const&
template<typename T>max(T a)
tempalte<>max(int a)
int
int&
0赞
anurag86
2/4/2020
另外,关于第二个问题 - 在没有变量名称的情况下,如何编译和运行它。
0赞
Sneaky Turtle
2/4/2020
如果您专注于并使用 an 进行呼叫,那么这与专业化不完全匹配(正如我在倒数第二段中所说),因此将使用基本模板。int &
int
2赞
Sneaky Turtle
2/4/2020
哦,我明白你的困惑了。的类型不是 。是的。这与专业化不完全匹配,因此使用基本模板。"hello"
const char *
const char [6]
1赞
Sneaky Turtle
2/4/2020
如果不使用函数参数,则无需提及其名称。顺便说一句,要专业化,您可以使用,因此将选择专业化。f
template<> void f(char const (&)[6])
f("hello")
评论
int max(int a, int b);