Следующий код прекрасно компилируется с 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
один).
Может ли кто-нибудь объяснить, почему перегрузки не являются неоднозначными? Насколько я могу судить, единственное различие между ними состоит в том, что аргумент первого — это не выводимый контекст, а аргумент второго — нет, но, поскольку я предоставляю аргумент шаблона явно, я не не понимаю, почему это должно иметь значение.
Обе перегрузки жизнеспособны, но первая более специализированный чем последний, и поэтому он выбирается разрешением перегрузки.
В соответствии с пунктом 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:
Частичное упорядочение выбирает, какой из двух шаблонов функций является более специализированным, чем другой, путем преобразования
каждый шаблон по очереди (см. следующий абзац) и выполнение вывода аргумента шаблона с помощью функции
тип. Процесс вывода определяет, является ли один из шаблонов более специализированным, чем другой. Если
Итак, более специализированный шаблон — это тот, который выбран в процессе частичного заказа.
Других решений пока нет …