为什么在模板元编程中使用enum而不是静态const bool被认为是更好的做法? 我在亚历山德列斯库的书中读到过这个但是找不到它,真的很想知道它。
答案 0 :(得分:7)
关键原因是静态bool毕竟是一个变量,而枚举是一个类型 - 因此在枚举的情况下,没有变量被实例化,因此它保证是编译时评估。
另请参阅this question了解详情。
答案 1 :(得分:7)
C ++标准(ISO / IEC 14882:2003)仅允许在整数常量表达式 的情况下使用静态const bool。
在预标准C ++中,所有静态数据成员(包括const成员)都需要在其类之外定义。但是,在C ++标准化过程中,决定解除静态const积分成员的这一要求。目的是允许诸如以下的用途:
struct C
{
static const int N = 10;
};
char data[C::N]; // N "used" without out-of-class definition
没有N的命名空间范围定义。
尽管如此,如果该成员被用于该计划,1998 C ++标准的措辞仍然需要一个定义。这包括成员出现在任何地方,除了作为sizeof或typeid的操作数,有效地使上述格式不正确。
这被确定为缺陷,并且调整了措辞以允许这样的成员出现在需要常量表达的任何地方,而不需要外部定义。这包括数组边界,case表达式,静态成员初始值设定项和非类型模板参数。
struct C
{
static const int N = 10;
static const int U = N; // Legal per C++03
};
char data[C::N]; // Legal per C++03
template<int> struct D;
template<> struct D<C::N> {}; // Legal per C++03
但是,除了需要使用整数常量表达式之外,在任何地方使用静态const积分成员都需要定义。但是大多数编译器都不会诊断出这种违规行为:
struct C
{
static const int N = 10;
};
int main()
{
int i = C::N; // ill-formed, definition of C::N required
}
然而,这个陷阱并不适用于枚举。
答案 2 :(得分:3)
这是一个旧的建议,它基于旧编译器的缺陷,这些缺陷与类定义中的static const
原语的内联初始化有关。 static bool const
是目前绝大多数惯用的做法。
来自C ++ 03标准,§9.4.2/ 4:
如果
static
数据成员是const
整数或const
枚举类型,则其在类定义中的声明可以指定 constant-initializer 是一个整数常数表达式(5.19)。在这种情况下,成员可以出现在整数常量表达式中。如果在程序中使用该成员,并且命名空间作用域定义不包含初始化程序,则该成员仍应在名称空间作用域中定义。