为什么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>()

我发现如果模板函数/类的第二个版本具有类型模板参数,这不是问题。如果模板函数/类的第二个版本具有整型的非类型模板参数,这也不是问题:

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

非类型模板参数的模板参数应为 转换后的模板参数类型的常量表达式。

10uintunsigned int类型的转换常量表达式。有效作为任一重载的参数。

最新更新