3

Why is it considered better practice to use enum not static const bool in template metaprogramming?
I've read that somewhere in Alexandrescu's book but cannot find it and really would like to know it.

There is nothing we can do
  • 23,727
  • 30
  • 106
  • 194

3 Answers3

7

The key reason is that a static bool is a variable after all and a enum is a type - hence in case of enum no variable is ever instantiated and it's thus guaranteed to be a compile-time evaluation.

Also see this question for more details.

Community
  • 1
  • 1
sharptooth
  • 167,383
  • 100
  • 513
  • 979
7

The C++ standard (ISO/IEC 14882:2003) permits the usage of a static const bool only where an integral constant-expression is required.

In pre-standard C++, all static data members (including const members) required a definition outside of their class. However, during the C++ standardization process it was decided to lift this requirement for static const integral members. The intent was to allow uses such as:

struct C
{
  static const int N = 10;
};
char data[C::N]; // N "used" without out-of-class definition

without a namespace scope definition for N.

Nevertheless, the wording of the 1998 C++ standard still required a definition if the member was used in the program. This included the member appearing anywhere except as the operand to sizeof or typeid, effectively making the above ill-formed.

This was identified as a defect, and the wording was adjusted to allow such a member to appear anywhere a constant expression is required, without requiring an out-of-class definition. This includes array bounds, case expressions, static member initializers, and nontype template arguments.

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

However, using a static const integral member anywhere except where an integral constant-expression is required requires a definition. But most compilers won't diagnose this violation:

struct C
{
  static const int N = 10;
};

int main()
{
  int i = C::N; // ill-formed, definition of C::N required
}

This pitfall, however, does not apply to enums.

decltype
  • 1,591
  • 8
  • 12
3

That's an old recommendation based on old compilers' deficiencies related to inline initialization of static const primitives inside of class definitions. static bool const is the overwhelmingly usual approach at this point.

From the C++03 standard, §9.4.2/4:

If a static data member is of const integral or const enumeration type, its declaration in the class definition can specify a constant-initializer which shall be an integral constant expression (5.19). In that case, the member can appear in integral constant expressions. The member shall still be defined in a namespace scope if it is used in the program and the namespace scope definition shall not contain an initializer.

ildjarn
  • 62,044
  • 9
  • 127
  • 211