5

推导的模板似乎是错误的,为什么调用(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*)

4

2 回答 2

3

好的,让我们先弄清楚我们有什么。

(a) 是一个函数模板。(b) 是该功能模板的特化。(c) 是另一个重载 (a) 的函数模板。

编写f(&p)时需要考虑两个重载:两个函数模板,(a) 和 (c)。(c)T*中比 (a) 中更专业T,因此 (c) 被选中。

现在让我们考虑注释掉的 (d)。这不是函数模板 (a) 的特化,而是额外的重载。为了解决f(&p)调用,现在需要考虑三个重载。(d) 不是模板并且int*与 的类型相匹配&p,因此它会优先于其他两个。

于 2013-06-12T07:34:54.113 回答
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*)
于 2013-06-12T07:40:15.840 回答