【发布时间】:2018-09-02 12:31:52
【问题描述】:
当我尝试这个时,编译器会出错。我尝试了 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>()?
我发现如果模板函数/类的第二个版本具有类型模板参数,这不是问题。如果模板函数/类的第二个版本具有 non-integral 类型的非类型模板参数,这也不是问题:
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++ 允许两个仅在整数参数类型上有所不同的重载函数。
【问题讨论】:
-
如果您使用特定类型,模板的意义何在?
-
将第二个版本更改为
template <signed int I, std::enable_if_t<(I < 0)>* = nullptr>将使其工作。 (正数选择无符号版本,负数选择有符号版本) -
非常感谢,使用 SFINAE 可能会帮助我完成我想要完成的工作。虽然这个问题主要是关于为什么 C++ 的行为方式。
-
Sagi,模板可以具有非类型模板参数,根据定义,这些参数属于具体类型。这在许多不同方面都很有用,这就是该语言包含该功能的原因。
标签: c++