Почему нет двусмысленности при выборе между шаблонными и не шаблонными функциями с одинаковыми сигнатурами? - PullRequest
0 голосов
/ 13 февраля 2019

Утверждается следующий код:

int foo() { return 1; }

template<typename T>
int foo() { return 2; }

int main() {
  assert( 1 == foo() );
  assert( 2 == foo<int>() );
  return 0;
}

Но, насколько я понимаю, согласно пункту 13.3.3 / 1 стандарта C ++ 11:

[...] С учетом этих определений жизнеспособная функция F1 определена как лучшая функция, чем другая жизнеспособная функция F2, если для всех аргументов i, ICSi(F1) не хуже последовательности преобразования, чем ICSi(F2), итогда [...] F1 - это не шаблонная функция, а F2 - это специализация шаблона функции [...]

Не должно быть, потому что подписи оказываются одинаковыми,Так почему нет двусмысленности, когда вызывается foo<int>()?Что мне не хватает?

1 Ответ

0 голосов
/ 13 февраля 2019

Текст, который вы цитируете, довольно плотный;Вы должны прочитать это внимательно.«F1 лучше, чем F2, если для всех аргументов i ICSi (F1) не хуже последовательности преобразования , чем ICSi (F2)» - это правда, поскольку две последовательности преобразования одинаковыследовательно, ни один не является хуже, чем другой.Итак, теперь вы переходите к последней части: «, а затем F1 - не шаблонная функция, а F2 - специализация шаблона функции».Это правда, поэтому F1 лучше, чем F2.Подставляя foo() и foo<int>() для F1 и F2 соответственно, правило гласит, что foo() лучше, чем foo<int>().

Ой, я ответил на неправильный вопрос.Как отмечается в комментарии, вопрос в том, почему явный вызов foo<int>() не приводит к foo()?И ответ таков: foo<int>() - это вызов явной реализации шаблона, а не вызов перегруженной функции.Рассмотрим:

template <class Ty>
void f(Ty) { }

void f(int);
void g(int);

f(3.14);      // calls f<double> (overloaded function call)
f(1);         // calls f(int) (overloaded function call)
f<int>(3.14); // calls f<int> (explicit call of template instantiation)
g(3.14);      // calls g(int)

В этом примере f<int> - это название специализации шаблона.Это , а не общая функция с именем f, поэтому перегрузку не нужно учитывать, как и при вызове g(3.14).

...