Reputation: 47900
Below are lines from "the c++ programming language"
template<class T > T sqrt(T );
template<class T > complex<T> sqrt(complex<T>);
double sqrt(double);
void f(complex<double> z )
{
s q r t (2 ); // sqrt<int>(int)
sqrt(2.0) ; // sqrt(double)
sqrt(z) ; // sqrt<double>(complex<double>)
}
I dont understand why sqrt(z) ; calls sqrt<double>(complex<double>)
can any body please explain.
Author says,
T sqrt<complex<T>>
is more specialized than T sqrt <T>
but there is a seperate declaration for template<class T > complex<T> sqrt(complex<T>);
why not use that?
Upvotes: 3
Views: 3499
Reputation: 179819
In hindsight, it would have been easier if Bjarne would have written it as
template<class T> T sqrt(T);
template<class U> complex<U> sqrt(complex<U>);
double sqrt(double);
void f(complex<double> z )
{
sqrt (2); // sqrt<int>(int)
sqrt(2.0) ; // sqrt(double)
sqrt(z) ; // sqrt<double>(complex<double>)
}
so you don't get confused by all the different T's. But the idea is simple; C++ finds the best match. There are three possible functions. The first two are perfect matches (no conversion needed) so the non-template version is ignored. Now, we have T=complex and U=double. Which version is chosen? Bjarne explains the second template is chosen here, because it's more specialized. This means that for any type U, there is a type T=complex<U>
which makes the signatures of both templates identical.
Upvotes: 6
Reputation: 43244
Well, the function used is the one you are talking about sqrt<double>(complex<double>)
is an instance of the template template <class T> complex<T> sqrt(complex<T>)
.
Your misunderstanding was in the signification of the template instance and not in the overloading process.
Upvotes: 2