Перегрузка шаблонной функции c ++ - PullRequest
3 голосов
/ 20 октября 2008

Ниже приведены строки из "языка программирования 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>);, почему бы не использовать это?

Ответы [ 2 ]

6 голосов
/ 20 октября 2008

Оглядываясь назад, было бы проще, если бы Бьярне написал бы это как

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 = complex и U = double. Какая версия выбрана? Бьярне объясняет, что второй шаблон выбран здесь, потому что он более специализированный. Это означает, что для любого типа U существует тип T=complex<U>, который делает подписи обоих шаблонов идентичными.

2 голосов
/ 20 октября 2008

Ну, используется та функция, о которой вы говорите sqrt<double>(complex<double>) - это экземпляр шаблона template <class T> complex<T> sqrt(complex<T>).

Ваше недоразумение было в значении экземпляра шаблона, а не в процессе перегрузки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...