为什么enum而不是静态bool?

时间:2011-03-01 07:39:01

标签: c++ metaprogramming

为什么在模板元编程中使用enum而不是静态const bool被认为是更好的做法? 我在亚历山德列斯库的书中读到过这个但是找不到它,真的很想知道它。

3 个答案:

答案 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)。在这种情况下,成员可以出现在整数常量表达式中。如果在程序中使用该成员,并且命名空间作用域定义不包含初始化程序,则该成员仍应在名称空间作用域中定义。