当我尝试此操作时,编译器给出了错误。我尝试了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>()
?
我发现如果模板函数/类的第二个版本具有类型模板参数,这不是问题。如果模板函数/类的第二个版本具有非整型的非类型模板参数,这也不是问题:
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++允许两个重载函数,这两个函数仅在整数参数的类型上有所不同。
它确实允许它,你能够很好地编写两个模板。它们只是在实例化时变得不可用。原因是没有"重载解决方案"来选择模板。对非类型模板参数施加的唯一要求如下:
[temp.arg.nontype]/2
非类型模板参数的模板参数应为 转换后的模板参数类型的常量表达式。
10u
是int
和unsigned int
类型的转换常量表达式。有效作为任一重载的参数。