Ниже приведены строки из «языка программирования C++»
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>)
}
Я не понимаю, почему sqrt (z); Звонки sqrt<double>(complex<double>) может любое тело объясните пожалуйста.
Автор говорит:
T sqrt<complex<T>> более специализирован, чем T sqrt <T>, но для template<class T > complex<T> sqrt(complex<T>); есть отдельная декларация, почему бы не использовать его?





Что ж, используемая функция - это та, о которой вы говорите, sqrt<double>(complex<double>) - это экземпляр шаблона template <class T> complex<T> sqrt(complex<T>).
Ваше недоразумение заключалось в значении экземпляра шаблона, а не в процессе перегрузки.
Оглядываясь назад, было бы легче, если бы Бьярн написал это как
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>)
}
так что вы не запутаетесь в разных «Т». Но идея проста; C++ находит лучшее совпадение. Возможны три функции. Первые два идеально подходят (преобразование не требуется), поэтому версия, не являющаяся шаблоном, игнорируется. Теперь у нас T = комплексный и U = двойной. Какая версия выбрана? Бьярн объясняет, что здесь выбран второй шаблон, потому что он более специализированный. Это означает, что для любого типа U существует тип T=complex<U>, который делает подписи обоих шаблонов идентичными.
Извините, ребята, я не понял sqrt <double> (сложный <double>) представляет собой сложный <double> sqrt <complex <double>>