Почему C++ не допускает использование двух шаблонов функций/классов с тем же именем, отличающихся только типом несимметричного шаблона (интегрального типа)?
Когда я пытаюсь это сделать, компилятор дает ошибку. Я пробовал как с VC++, так и с g++.
Это в равной степени относится к шаблонам функций и шаблонам классов (хотя для шаблонов функций ошибка компилятора возникает только в том случае, когда и когда создается шаблон функции, ошибка компилятора для шаблона класса происходит сразу же, когда компилятор сталкивается с определением второго класса).
Вот пример шаблона функции:
template <unsigned int>
void Foo() {}
template <signed int> // Same name, only difference is the type of the
void Foo() {} // non-type template parameter (of integral type)
Foo<10U>(); // COMPILER ERROR.
Выше, почему компилятор не может создать экземпляр Foo <unsigned int>()?
Я обнаружил, что это не проблема, если вторая версия шаблона function/class имеет параметр шаблона типа. Это также не проблема, если вторая версия функции шаблона/класса имеет или несимметричный шаблонный параметр нецелого типа:
template <unsigned int>
void Foo() {}
template <unsigned int*> // Non-type template parameter
void Foo() {} // of non-integral type
template <typename T> // Type template parameter
void Foo() {}
Foo<10U>(); // OK
Так что, если бы я должен был догадаться, я бы сказал, что он имеет какое-то отношение к тому, что компилятор может преобразовывать значения интегральных типов? Но это не останавливает C++ от допуска двух функций перегрузки, которые отличаются только типом интегрального параметра.
Спасибо!
Ответы
Ответ 1
Это действительно так, вы смогли написать два шаблона просто отлично. Они просто становятся непригодными при создании экземпляров. Причина в том, что для выбора шаблона нет "разрешения перегрузки". Единственное требование, наложенное на аргумент шаблона, отличного от типа, выглядит следующим образом:
[temp.arg.nontype]/2
Аргумент шаблона для не-type template-parameter должен быть преобразованным константным выражением типа шаблона-параметра.
И 10u
- преобразованное константное выражение как int
и unsigned int
type. Действителен как аргумент для перегрузки.