根据The C++ Programming Language,Special Edition,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)
}
Run Code Online (Sandbox Code Playgroud)
他说,尽管两个模板都是有效的候选者,但第二个模板sqrt<double>(complex<double>)将优先于第一个,因为它是最专业的模板.
我尊敬的编译器,gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04)似乎不同意:
ft.cpp: In function ‘void f(std::complex<double>)’:
ft.cpp:28:11: error: call of overloaded ‘sqrt(std::complex<double>&)’ is ambiguous
sqrt(z);
^
ft.cpp:28:11: note: candidates are:
ft.cpp:9:21: note: T sqrt(T) [with T = std::complex<double>]
template<class T> T sqrt(T);
^
ft.cpp:10:30: note: std::complex<_Tp> sqrt(std::complex<_Tp>) [with T = double]
template<class T> complex<T> sqrt(complex<T>);
^
Run Code Online (Sandbox Code Playgroud)
我做错了什么(虽然我复制了角色的代码字符)?或者它是我的编译器的实现错误?
完整的错误消息揭示了另外一个候选者:
/usr/local/include/c++/5.3.0/complex:894:5:注意:候选者:std::complex<_Tp> std::sqrt(const std::complex<_Tp>&) [with _Tp = double ]
即,存在于命名空间中的那个std,即 的std::sqrt重载std::complex。由于您使用的是非限定名称,因此查找规则将扩展为在函数调用参数 ( ADL )的命名空间中搜索函数。解决办法如下:
更改函数的名称sqrt,以便它不会与标准库中的任何函数发生冲突。
引用函数时使用限定名称:
::sqrt(z);
Run Code Online (Sandbox Code Playgroud)
通过使用括号禁用 ADL:
(sqrt)(z);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
140 次 |
| 最近记录: |