Функция шаблона перегружена одинаковыми сигнатурами, почему это работает?
Минимальная программа:
#include
#include
template
int foo(typename T::type s) {
return 1;
}
template
int foo(S s) {
return 2;
}
int main(int argc, char* argv[]) {
int x = 3;
printf("%d\n", foo(x));
return 0;
}
выход:
1
Почему нетЭто дает ошибку компиляции? Когда код шаблона генерируется, не будетт функцииint foo(typename T::type search)
а такжеint foo(S& search)
есть такая же подпись?
Если вы немного измените сигнатуры функций шаблона, они все равно будут работать (как я и ожидал, учитывая приведенный выше пример):
template
void foo(typename T::type s) {
printf("a\n");
}
template
void foo(S s) {
printf("b\n");
}
Все же это неt, и все же единственное отличие состоит в том, что один из них имеет сигнатуру int, а другой определяется первым параметром шаблона.
template
void foo(typename T::type s) {
printf("a\n");
}
template
void foo(int s) {
printf("b\n");
}
Ошибка компилятора (лязг): I '
test.cpp:26:2: error: call to 'foo' is ambiguous
foo(3);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test.cpp:16:6: note: candidate function [with T = std::__1::enable_if]
void foo(typename T::type s) {
^
test.cpp:21:6: note: candidate function [with T = std::__1::enable_if]
void foo(int s) {
^
1 error generated.
Я использую код, подобный этому для проекта, который яя работаю надбоюсь, что тамтонко для языка, который яЯ не понимаю, что в некоторых случаях может привести к неопределенному поведению. Я должен также упомянуть, что он компилируется как на Clang, так и на VS11, поэтому я нене думаю, что этоЭто просто ошибка компилятора.
Редактировать: Исправлено второе дело (опечатка); добавлено сообщение об ошибке от Clang.
Edit # 2: Для тех из вас, кто спросил, что означает T :: type.
Отhttp://en.cppreference.com/w/cpp/types/enable_if:
шаблон < bool B, класс T = void> struct enable_if;
Если B истинно, std :: enable_if имеет открытый тип typedef, равный T; в противном случае, нет члена typedef.
enable_if - это структура. По сути, если выражение, вычисленное в первом параметре шаблона enable_if, имеет значение true (а в случае с моими примерами выше это так), тогда будет открытый членtype
имеет тот же тип, что и второй параметр шаблона.
В случаеenable_if
, enable_if :: type имеет тип int.