函数模板重载 - 专用化
Function Template Overloading - Specialization
根据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)
似乎不同意:
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>);
^
我做错了什么吗(尽管我复制了代码字符(?还是我的编译器的实现错误?
完整的错误消息揭示了另一个候选项:
/usr/local/include/c++/5.3.0/complex:894:5: 注意:候选:std::complex<_Tp> std::sqrt(const std::complex<_Tp>&( [_Tp = double]
即,存在于std
命名空间中的那个,即std::complex
的std::sqrt
重载。由于使用的是非限定名称,因此查找规则将扩展为在函数调用参数 (ADL( 的命名空间中搜索函数。解决方案如下:
选项 #1
更改 sqrt
函数的名称,使其不会与标准库中的任何函数发生冲突。
选项 #2
引用函数时使用限定名:
::sqrt(z);
选项 #3
通过使用括号禁用 ADL:
(sqrt)(z);
相关文章:
- 使用类指针重载C++命名空间函数模板专用化替代方法?
- 模板专用化与函数重载
- C++函数模板专用化和重载
- 函数模板重载 - 部分专用化
- 专用和/或重载具有可变参数的成员函数模板
- 模板专用类之间的构造函数重载
- 通过重载实现部分模板专用化
- 如何为模板类的所有实例专用化或重载全局模板函数
- 对于重载函数,为父实例和子实例调用专用版本
- 部分专用结构与重载函数模板
- 部分模板专用化可能不适用于函数,但重载不是一回事吗?
- 运算符<<重载时无法访问专用成员(指定指针)
- 为什么重载优先于ADL中的显式专用化
- 重载特定模板专用化的成员函数
- 运算符重载和模板专用化
- 以下语句是函数重载还是函数部分专用化
- 函数模板重载 - 专用化
- 带有重载的显式模板函数专用化:为什么要这样做
- 重载运算符'<<'(左移)的显式专用化
- 在模板专用化和重载 C++ 方面没有预期的歧义