我正在学习c ++中的模板,并且发现了以下示例。
据我了解,如果没有匹配的非模板函数,编译器应始终尝试使用最“专业化”的模板,但是在此示例中,第一次调用导致调用函数a(T *)而不是a(int) *)。为什么?为何第二通电话的行为有所不同?
template<typename T>
void a(T) {cout << "(T)" << endl;}
template<>
void a<>(int*) {cout << "(int)" << endl;}
template<typename T>
void a(T*) {cout << "(T*)" << endl;}
template<typename T>
void b(T) {cout << "(T)" << endl;}
template<typename T>
void b(T*) {cout << "(T*)" << endl;}
template<>
void b<>(int*) {cout << "(int)" << endl;}
int main()
{
int i;
a(&i);
b(&i);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
结果输出为:
(T*)
(int)
Run Code Online (Sandbox Code Playgroud)
我期望它是:
(int)
(int)
Run Code Online (Sandbox Code Playgroud)
选择主要的模板过载(因此不需专门化)即可。
一旦使用主模板完成选择,我们将使用专业化(如果有)。
现在,template<> void a<>(int*);只能进行专门化template<typename T> void a(T)(其他版本尚未见)。
并且template<> void b<>(int*);是的专业化template<typename T> void b(T*)(它是更专业的匹配重载)。
请注意,您可以b通过提供模板而不是让编译器推断来选择的特化:
template<> void b<>(int*) -> template<typename T> void b(T*) with T=inttemplate<> void b<int>(int*) -> template<typename T> void b(T*) with T=inttemplate<> void b<int*>(int*) -> template<typename T> void b(T) with T=int*因此对于:
int i;
a(&i); // a<T*> with T=int*, no specialization for a<U*> (U=int) exist -> generic template called
b(&i); // b<T*> with T=int*, specialization for b<U*> (U=int) exists -> specialization called
Run Code Online (Sandbox Code Playgroud)