Вкратце, правила для включения шаблонов функций в разрешение перегрузки:
Поиск имени определяет набор видимых функций, объектов и шаблонов функций.
Каждый шаблон функции в наборе определяет свои аргументы шаблона из любых явных аргументов, вычетов и / или аргументов шаблона по умолчанию, и они заменяются, чтобы получить одну конкретную сигнатуру конкретной функции, если это возможно.(Если это невозможно, шаблон функции просто выбрасывается из набора. Это может произойти, если не удается вывести аргументы шаблона и если не удается подставить аргументы в сигнатуру, то есть правило «SFINAE».)
Функции сравниваются с использованием нормальных правил разрешения перегрузки, при этом сигнатуры, полученные из шаблонов, обрабатываются точно так же, как если бы они были обычными не шаблонными функциями.
Только если на шаге 3рассмотрим две функции неоднозначно, применяются эти прерыватели:
а.Если одна сигнатура функции пришла из шаблона, а другая - нет, то функция без шаблона считается лучшей.
b.Если обе подписи функций взяты из шаблонов, и один шаблон «более специализирован», чем другой, то более специализированный шаблон считается лучшим.(Вкратце, «более специализированный» означает, по сути, что мы можем доказать, что любые действительные аргументы для более специализированного шаблона также являются действительными аргументами для менее специализированного шаблона, но не наоборот.)
В выражении f(p)
этого примера на шаге 2 шаблон # 1 выводит T=int*
, а шаблон # 2 выводит T=int
, поэтому сигнатуры:
void f(int*); // from 1
void f(const int*); // from 2
На шаге 3 аргумент p
имеет тип int*
, поэтому void f(int*);
из # 1 использует преобразование идентификаторов (точное совпадение), а void f(const int*);
из # 2 использует преобразование указателей, поэтому void f(int*);
из # 1 выигрывает, и специализация шаблона функциитот, который назван.
Это правда, что шаблон # 2 void f(const T*);
более специализирован, чем шаблон # 1 void f(T);
.Но поскольку шаг 3 определил ответ, мы никогда не перейдем к шагу 4, так что это не имеет значения(Шаг 4 подходит для другого выражения f(p2)
.)