Functional Template Overloading - Specialization

According to the C ++ Special Edition programming language, 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 claims that although both templates are valid candidates, the second, sqrt<double>(complex<double>) will be preferable to the first, as it is the most specialized template.

My respected compiler, gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04) does not seem to agree:

 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 for the character)? Or is it an implementation error for my compiler?

+5
source share
1 answer

In the full error message, another candidate appears:

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

ie, which is in the std , namely std::sqrt overload for std::complex . Because you are using an unqualified name, the search rules are expanded to search for functions in function name argument argument spaces ( ADLs ). The solutions are as follows:

Option number 1

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

Option number 2

Use a qualified name when accessing your function:

 ::sqrt(z); 

Option number 3

Disable ADL with brackets:

 (sqrt)(z); 
+2
source

Source: https://habr.com/ru/post/1242950/


All Articles