Почему эти перегрузки неоднозначны?

Следующий код прекрасно компилируется с gcc и clang.

template <typename T>
struct identity
{
typedef T type;
};

template <typename T>
void foo(typename identity<T>::type);

template <typename T>
void foo(T);

int main()
{
foo<int>(0);
}

Похоже, что разрешение перегрузки выбирает первую перегрузку ( identity<T>::type один).

Может ли кто-нибудь объяснить, почему перегрузки не являются неоднозначными? Насколько я могу судить, единственное различие между ними состоит в том, что аргумент первого — это не выводимый контекст, а аргумент второго — нет, но, поскольку я предоставляю аргумент шаблона явно, я не не понимаю, почему это должно иметь значение.

7

Решение

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

В соответствии с пунктом 13.3.3 / 1 стандарта C ++ 11 по разрешению перегрузки:

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

— для некоторого аргумента j, ICSj(F1) является лучшей последовательностью преобразования, чем ICSj(F2)или, если не так,

— контекст является инициализацией путем пользовательского преобразования (см. 8.5, 13.3.1.5 и 13.3.1.6) и
стандартная последовательность преобразования из типа возврата F1 в тип назначения (то есть тип
инициализируемая сущность) является лучшей последовательностью преобразования, чем стандартная последовательность преобразования из
тип возврата F2 к типу назначения. […] или, если не это,

F1 это не шаблонная функция и F2 это специализация шаблона функции, или, если не так,

F1 а также F2 являются специализациями шаблонов функций, а шаблон функций для F1 более специализированный
чем шаблон для F2 в соответствии с правилами частичного заказа, описанными в 14.5.6.2.

Процесс определения того, какой из двух шаблонов функций является более специализированным, чем другой, описан в пункте 14.5.6.2/2:

Частичное упорядочение выбирает, какой из двух шаблонов функций является более специализированным, чем другой, путем преобразования
каждый шаблон по очереди (см. следующий абзац) и выполнение вывода аргумента шаблона с помощью функции
тип. Процесс вывода определяет, является ли один из шаблонов более специализированным, чем другой. Если
Итак, более специализированный шаблон — это тот, который выбран в процессе частичного заказа.

7

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]