17 Templates [temp]

17.8 Function template specializations [temp.fct.spec]

17.8.3 Overload resolution [temp.over]

Шаблон функции может быть перегружен либо (не шаблонными) функциями его имени, либо (другими) шаблонами функций с тем же именем. Когда вызов этого имени записан (явно или неявно с использованием обозначения оператора), template argument deduction и проверка любого явного template arguments значения выполняется для каждого шаблона функции, чтобы найти значения аргументов шаблона (если есть), которые можно использовать с этим шаблоном функции для создания экземпляра специализация шаблона функции, которая может быть вызвана с аргументами вызова. Для каждого шаблона функции, если вывод аргументов и проверка завершаются успешно, template-arguments (выведенные и / или явные) используются для синтеза объявления специализации шаблона одной функции, которая добавляется к набору функций-кандидатов, которые будут использоваться при разрешении перегрузки. Если для данного шаблона функции выведение аргументов не удается или специализация шаблона синтезированной функции была бы неправильно сформирована, такая функция не добавляется к набору функций-кандидатов для этого шаблона. Полный набор функций-кандидатов включает все синтезированные объявления и все одноименные перегруженные функции, не являющиеся шаблонными. Синтезированные объявления обрабатываются как любые другие функции в оставшейся части разрешения перегрузки, за исключением случаев, явно указанных в [over.match.best].143

[Example:

template<class T> T max(T a, T b) { return a>b?a:b; }

void f(int a, int b, char c, char d) {
  int m1 = max(a,b);            // max(int a, int b)
  char m2 = max(c,d);           // max(char a, char b)
  int m3 = max(a,c);            // error: cannot generate max(int,char)
}

Добавление нешаблонной функции

int max(int,int);

в приведенном выше примере разрешит третий вызов, предоставив функцию, которая может быть вызвана max(a,c) после использования стандартного преобразования char в int for c. ]end example

[ Example: Вот пример преобразования аргумента функции, участвующего в template-argument дедукции:

template<class T> struct B { /* ... */ };
template<class T> struct D : public B<T> { /* ... */ };
template<class T> void f(B<T>&);

void g(B<int>& bi, D<int>& di) {
  f(bi);            // f(bi)
  f(di);            // f((B<int>&)di)
}

end example]

[ Example: Вот пример преобразования аргумента функции, не участвующего в template-parameter дедукции:

template<class T> void f(T*,int);       // #1
template<class T> void f(T,char);       // #2

void h(int* pi, int i, char c) {
  f(pi,i);          // #1: f<int>(pi,i)
  f(pi,c);          // #2: f<int*>(pi,c)

  f(i,c);           // #2: f<int>(i,c);
  f(i,i);           // #2: f<int>(i,char(i))
}

end example]

Для ввода специализации в набор функций-кандидатов требуется только подпись специализации шаблона функции. Следовательно, для разрешения вызова, для которого возможна специализация шаблона, требуется только объявление шаблона функции. [Example:

template<class T> void f(T);    // declaration

void g() {
  f("Annemarie");               // call of f<const char*>
}

Вызов f правильно сформирован, даже если шаблон f только объявлен и не определен в точке вызова. Программа будет плохо сформирована, еслиf<const char*>в некоторой единице трансляции не будет присутствовать явно или неявно сгенерированная специализация for . ] end example

Параметры специализаций шаблонов функций не содержат типов параметров шаблона. Набор преобразований, разрешенных для выведенных аргументов, ограничен, потому что процесс вывода аргументов создает шаблоны функций с параметрами, которые либо точно соответствуют аргументам вызова, либо отличаются только способами, которые могут быть объединены разрешенными ограниченными преобразованиями. Невыведенные аргументы допускают полный диапазон преобразований. Также обратите внимание, что это [over.match.best] указывает, что функции, не являющейся шаблоном, будет отдано предпочтение по сравнению со специализацией шаблона, если в остальном эти две функции являются одинаково хорошими кандидатами на совпадение по перегрузке.