功能模板重载 - 专业化

时间:2016-02-13 11:44:23

标签: c++

根据 C ++编程语言,特别版, Bjarne Stroustrup ,第13.3.2节:

template<class T> T sqrt(T);
template<class T> complex<T> sqrt(complex<T>);

void f(complex<double> z)
{
    sqrt(z);      // sqrt<double>(complex<double)
}   

他说,尽管两个模板都是有效候选者,但第二个模板优先于第一个,因为它是最专业的模板。

我尊敬的编译器,sqrt<double>(complex<double>)似乎不同意:

gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04)

我做错了什么(虽然我复制了角色的代码字符)?或者它是我的编译器的实现错误?

1 个答案:

答案 0 :(得分:2)

完整的错误消息显示还有一个候选人:

  

/ usr / local / include / c ++ / 5.3.0 / complex:894:5:note:candidate:std :: complex&lt; _Tp&gt; std :: sqrt(const std :: complex&lt; _Tp&gt;&amp;)[with _Tp = double]

,即位于std命名空间的那个,即std::complex的{​​{3}}重载。由于您使用的是非限定名称,因此查找规则将扩展为在函数调用参数(std::sqrt)的名称空间中搜索函数。解决方案如下:

选项#1

更改sqrt功能的名称,使其不会与标准库中的任何功能冲突。

选项#2

在提及您的功能时使用限定名称:

::sqrt(z);

选项#3

通过使用括号来禁用ADL:

(sqrt)(z);