C ++函数模板专门化和重载

时间:2017-06-19 07:10:15

标签: c++ templates overloading explicit-specialization

考虑此代码:

template <class T>
void f(T p) {           //(1)
    cout << "Second" << endl;
}

template <>
void f(int *p) {        //(2)
    cout << "Third" << endl;
}


template <class T>
void f(T* p) {          //(3)
    cout << "First" << endl;
}

int *p; f(p);之类的通话会输出First

如果声明的顺序发生了变化,如下所示:

template <class T>
void f(T* p) {          //(3)
    cout << "First" << endl;
}


template <class T>
void f(T p) {           //(1)
    cout << "Second" << endl;
}

template <>
void f(int *p) {        //(2)
    cout << "Third" << endl;
}

同一个电话(int *p; f(p);)将输出Third

我读到了函数模板重载解析发生的方式:首先,解析只考虑非模板函数底层基本模板。在&#34;最专业的&#34;选择一个,如果它是一个模板函数,并且它具有对推导(或明确指定)的参数的特化,则调用该特化。

现在我的问题是:如何确定哪个底层基本模板一个函数是一个特化?在我的例子中,哪个函数模板重载((1)或(3))是(2)一个特化?

我的猜测是,当声明一个特化时,会考虑已经声明的模板,并从那些最常用的模板中考虑#34; (选择参数为&#34;最接近&#34;此专业化)。它是否正确?另外,您能指出我在标准中指定的位置吗?

1 个答案:

答案 0 :(得分:3)

它打印&#34;第一&#34;因为声明的顺序会影响你实际上专门化的模板。

您的示例有两个函数模板,它们重载相同的名称。在第一种情况下,您会专注void f(T p),因为它是目前为止看到的唯一模板。

在第二种情况下,它是void f(T* p)专门的。{{1}}。所以是的,你的猜测是正确的。具体内容为[temp.deduct.decl/1]

  

在声明中,声明者id指的是a的特化   函数模板,执行模板参数推导   确定声明所指的专业化。   具体来说,这是为了显式实例化,显式   专业化,和某些朋友声明。 [...]

这包括功能模板的部分排序。但是,部分排序仅适用于您引入专业化时可用的函数模板声明。

标准警告[temp.expl.spec/7]

  

功能模板的显式专业化声明的放置,[...],会影响程序是否格式正确   根据显式专业化的相对定位   声明及其在翻译单元中的实例化要点   如上下文所述。写专业时,请   小心它的位置;或者使它编译将是这样的试验   点燃自焚。