template<class T> T sqrt (T);
template<class T> complex<T> sqrt(complex<T>);
double sqrt(double);
void f(complex<double> z)
{
sqrt(z);
}
Как в этом коде sqrt<double>(complex<double>) оказывается кандидатом на вывод аргумента шаблона? И автор говорит, что любой вызов, который соответствует sqrt<T>(complex<T>), также соответствует sqrt<T>(<T>). Как?
Код взят из Языка программирования C++ Бьярна Страуструпа. Раздел 13.3.2
Ответ 1 · рейтинг 7 · Dietmar Kühl
Ну, z относится к типу complex<double>. Поскольку T означает double, это явно соответствует
template <typename T> complex<T> sqrt(complex<T>);
Кроме того, если T равно complex<double>, это соответствует
template <typename T> T sqrt(T);
Где проблема с этим?
В результате сопоставления обеих этих функций набор перегрузки для принятия решения о том, какую из функций использовать, состоит из двух экземпляров
complex<double> sqrt<double>(complex<double>)
complex<double> sqrt<complex<double>>(complex<double>)
Оба совпадают, но первый является более специализированным и поэтому выбирается по разрешению перегрузки.