第3章 非类型模板参数:3.3 非类型模板参数的限制

3.3 Restrictions for Nontype Template Parameters

3.3 非类型模板参数的限制

Note that nontype template parameters carry some restrictions. In general, they can

be only constant integral values (including enumerations), pointers to objects/functions/members, lvalue references to objects or functions, or std::nullptr_t (the type of nullptr).

注意,非类型模板参数是有限制的。通常而言,他们只能是常整数(包括枚举)、对象/函数/成员的指针、对象或函数的左值引用,或者是std::nullptr_t(nullptr的类型)。

Floating-point numbers and class-type objects are not allowed as nontype template

parameters:

浮点数和类对象是不允许作为非类型模板参数的:

template<double VAT> // ERROR: 浮点数不能作为非类型模板参数
double process (double v) // 但可以作为模板参数
{
    return v * VAT;
}
 
template<std::string name> // ERROR: 类类型不能作为非类型模板参数
class MyClass { // allowed as template parameters
    …
};

When passing template arguments to pointers or references, the objects must not be string literals, temporaries, or data members and other subobjects. Because these restrictions were relaxed with each and every C++ version before C++17, additional constraints apply:

将指针或引用传入模板实参时,对象不能是字符串字面量、临时对象或数据成员和其他子对象。因为C++17之前的每一个C++版本都放宽了这些限制,额外的限制适用于:

• In C++11, the objects also had to have external linkage.

  在C++11中,对象还必须具有外部链接的。

• In C++14, the objects also had to have external or internal linkage.

  在C++14中,对象还必须是外部或内部链接。

Thus, the following is not possible:

因此,下面是不可能的:

template<char const* name>
class MyClass {
    …
};

MyClass<"hello"> x; //ERROR: 不允许使用字符串字面量( "hello" )

However there are workarounds (again depending on the C++ version):

然而,有一些解决方法(再一次依赖于C++版本):

extern char const s03[] = "hi"; // 外部链接
char const s11[] = "hi"; // 内部链接

int main()
{
    Message<s03> m03; // OK (所有版本)
    Message<s11> m11; // OK,从 C++11开始
    static char const s17[] = "hi"; // 无链接(静态局部变量为无链接?)
    Message<s17> m17; // OK,从 C++17开始
}

In all three cases a constant character array is initialized by "hello" and this object is used as a template parameter declared with char const*. This is valid in all C++ versions if the object has external linkage (s03), in C++11 and C++14 also if it has internal linkage (s11), and since C++17 if it has no linkage at all.

在这三种情况中,常量字符数组对象都是由“hello”会初始化的。在声明为char const*模板参数中使用了该对象。如果该对象是一个外部链接(s03),那么在C++所有的版本都是有效的。在C++11和C++14中,如果对象是一个内部链接,也会有效。从C++17开始,如果对象根本没有链接,也会有效。

See Section 12.3.3 on page 194 for a detailed discussion and Section 17.2 on page 354 for a discussion of possible future changes in this area.

有关详细讨论,请参阅第194页的12.3.3节。关于这个地方将来可能发生变化的讨论,请参阅第354页的17.2节。

Avoiding Invalid Expressions

避免无效表达式

Arguments for nontype template parameters might be any compile-time expressions.

For example:

非类型模板参数可以是任何编译期的表达式。

template<int I, bool B>
class C;
…
C<sizeof(int) + 4, sizeof(int)==4> c;

However, note that if operator> is used in the expression, you have to put the whole expression into parentheses so that the nested > ends the argument list:

但是,请注意,如果己经在表达式中使用了”>”运算符,就必须把整个表达式放入圆括号中以便嵌套的>结束实参列表:

C<42, sizeof(int) > 4> c; // ERROR: 第1个“ > ”结束了模板实参列表

C<42, (sizeof(int) > 4)> c; // OK

猜你喜欢

转载自www.cnblogs.com/5iedu/p/12716483.html