模板演绎似乎是错误的

Template deduction seems wrong

本文关键字:错误 似乎是 演绎      更新时间:2023-10-16

模板推导似乎不对,为什么叫(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*)

好吧,让我们先理清头绪。

(a)是一个函数模板。(b)是该函数模板的专门化。(c)是重载(a)的另一个函数模板。

当你写f(&p)时,有两个重载要考虑:两个函数模板,(a)和(c)。(c)中T*比(a)中的T更专门化,所以(c)被选中。

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

模板专门化必须在模板之后。在这里,在您的例子中,它看起来像这样:

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*)