Оба шаблона обеспечивают точное соответствие аргументу — второй шаблон требует (допустимого) преобразования из массива в указатель, и это преобразование считается точным соответствием при подборе функции (см. раздел 6.6.1). Нешаблонная версия является подходящей, но требует пользовательского преобразования. Эта функция хуже точного соответствия, поэтому кандидатами остаются два шаблона. Как и прежде, версия Т*
более специализирована, она и будет выбрана.
Если символьные указатели необходимо обработать как строки, можно определить еще две перегруженные, нешаблонные функции:
//
//
string debug_rep(char *p) {
return debug_rep(string(p));
}
string debug_rep(const char *p) {
return debug_rep(string(p));
}
Следует заметить, что для правильной работы версии char*
функции debug_rep()
объявление debug_rep(const string&)
должно находиться в области видимости, когда эти функции определяются. В противном случае будет вызвана неправильная версия функции debug_rep()
:
template
template
//
//
string debug_rep(const string &);
string debug_rep(char *p) {
//
//
//
return debug_rep(string(p));
}
Обычно, если попытаться использовать функцию, которую забыли объявлять, код не будет откомпилирован. Но с функциями, которые перегружают шаблон функции, все не так. Если компилятор может создать экземпляр вызова из шаблона, то отсутствие объявления не будет иметь значения. В этом примере, если забыть объявлять версию функции debug_rep()
, получающую строку, компилятор const Т&
.
Упражнение 16.48. Напишите собственные версии функций debug_rep()
.
Упражнение 16.49. Объясните, что происходит в каждом из следующих вызовов:
template
template
template
template
int i = 42, *p = &i
const int ci = 0, *p2 = &ci
g(42); g(p); g(ci); g(p2);
f(42); f(p); f(ci); f(p2);
Упражнение 16.50. Определите функции из предыдущего упражнения так, чтобы они выводили идентификационное сообщение. Выполните код этого упражнения. Если вызовы ведут себя не так, как ожидалось, выясните почему.
Для указания, что шаблону или функции представлен пакет параметров, используется многоточие. В списке параметров шаблона синтаксис class...
или typename...
означает, что следующий параметр представляет список любого количества типов; имя типа, сопровождаемое многоточием, представляет список из любого количества параметров значения заданного типа. Параметр в списке параметров функции, типом которого является пакет параметров шаблона, представляет собой пакет параметров функции. Например:
//