Search code examples
c++templatesargumentstemplate-argument-deduction

In template argument deduction how does sqrt<T>(complex<T>) matche sqrt<T>(<T>) function call?


template<class T> T sqrt (T);
template<class T> complex<T> sqrt(complex<T>);
double sqrt(double);
void f(complex<double> z)
{
    sqrt(z);
}

In this code how does sqrt<double>(complex<double>) end up as a candidate for template argument deduction? And the author says any call that matches sqrt<T>(complex<T>) also matches sqrt<T>(<T>). How?

Code is from The C++ Programming Language, by Bjarne Stroustrup. Section 13.3.2


Solution

  • Well, z is of type complex<double>. With T being double it clearly matches

    template <typename T> complex<T> sqrt(complex<T>);
    

    Also, with T being complex<double> it matches

    template <typename T> T sqrt(T);
    

    Where is the problem with this?

    As the result of matching both of these functions, the overload set for deciding which of the functions to use consists of the two instantiations

    complex<double> sqrt<double>(complex<double>)
    complex<double> sqrt<complex<double>>(complex<double>)
    

    Both match but the first one is more specialized and, thus, chosen by the overload resolution.