推断的模板似乎是错误的,为什么(c)被调用而不是(b)?
#include <iostream>
using namespace std;
template<class T> void f(T){cout << "f(T)";}//(a)
template<> void f<>(int*){cout << "f(int*)";}//(b)
template<class T> void f(T*){cout << "f(T*)";}//(c)
//void f(int*){cout <<"POD:f(int*)";}//(d)
int main(int argc,char*argv[])
{
int p = 1;
f(&p);
cout <<endl;
return 0;
}
输出
f(T*)
答案 0 :(得分:3)
好的,让我们先说清楚我们先拥有的东西。
(a)是一个功能模板。 (b)是该功能模板的专业化。 (c)是另一个重载(a)的函数模板。
当您编写f(&p)
时,需要考虑两个重载:两个函数模板,(a)和(c)。在(c)中,T*
比(a)中的T
更专业,因此(c)被选中。
现在让我们考虑一下注释(d)。这不是函数模板(a)的特化,而是额外的重载。要解决f(&p)
调用,现在需要考虑三个重载。 (d)不是模板,并且int*
与&p
的类型相匹配,因此它会被其他两个选中。
答案 1 :(得分:0)
模板专业化必须在模板之后。 在这种情况下,它看起来像这样:
template<class T> void f(T){cout << "f(T)";}//(a) // Template 1
template<> void f<>(int*){cout << "f(int*)";}//(b) // Specialization of template 1
template<class T> void f(T*){cout << "f(T*)";}//(c) // Template 2, conceals template 1
因此,您可以实例化模板2。 正确的做法是:
template<class T> void f(T*){cout << "f(T*)";} // Template 1
template<class T> void f(T){cout << "f(T)";} // Template 2
template<> void f<>(int*){cout << "f(int*)";} // Specialization of the template 1
输出:
f(int*)