简体   繁体   中英

Function Template Overloading - Specialization

According to The C++ Programming Language, Special Edition, Bjarne Stroustrup , section 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)
}   

He states, that although both templates are valid candidates, the second one, sqrt<double>(complex<double>) will be preferred over the first one, because it is the most specialized template.

My esteemed compiler, gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04) seems to disagree:

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>);
                          ^

Am I doing something wrong (although I copied the code character for character)? Or is it an implementation error for my compiler?

The complete error message reveals one more candidate:

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

ie, the one that lives in the std namespace, namely the std::sqrt overload for std::complex . Since you're using an unqualified name, the lookup rules are extended to search the function in the namespaces of function call arguments ( ADL ). The solutions are as follows:

Option #1

Change the name of your sqrt function so that it does not collide with any from the standard library.

Option #2

Use a qualified name when referring to your function:

::sqrt(z);

Option #3

Disable ADL by means of using parenthesis:

(sqrt)(z);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM