views:

126

answers:

2
namespace ValueType {
  enum Enum {
    Boolean = 0,
    Float = 1,
    Double,
    SInt = 8,
    SLong,
    UInt = SInt + (1 <<4),
    ULong = SLong + (1 << 4)
  };
}
+13  A: 

Yes -- the requirement is that it's an integral constant expression. The C++ standard includes the following example:

enum { d, e, f=e+2 };
Jerry Coffin
When I saw your answer and Pavel's above I was immediately reminded of boost and meta-programming, how did I not remember that? heh.Thanks. :)
Geoff
It is even possible to use booleans: **enum { yes = true, no = !yes};**
fmuecke
Yes, according to the rules of C++, the *integral types* include "bool, char, wchar_t, the signed and unsigned integer types", and "bool values behave as integral types."
Jerry Coffin
+1  A: 

As pointed out by Jerry, it is legal.

In some rare cases its wroth being aware that the type of the enumerators are only specified after the enumeration is fully defined. The standard says the following about the type of the enumerations (7.2/4):

Each enumeration defines a type that is different from all other types. Following the closing brace of an enum-specifier, each enumerator has the type of its enumeration. Prior to the closing brace, the type of each enumerator is the type of its initializing value. If an initializer is specified for an enumerator, the initializing value has the same type as the expression. If no initializer is specified for the first enumerator, the type is an unspecified integral type. Otherwise the type is the same as the type of the initializing value of the preceding enumerator unless the incremented value is not representable in that type, in which case the type is an unspecified integral type sufficient to contain the incremented value.

The highlighted sentence can be shown in the following example:

enum E {
  E0            // Unspecified type
  , E1 = E0-1   // -1, or MAX_UINT
  , E2          // 0 or (MAX_UINT+1)
};

Basically, the type chosen for E0 affects the resulting value of E1.

Richard Corden
Understandable and logical, I don't see why someone would avoid giving an initial value though. Doing that pointlessly puts you at the mercy of the compiler's implementation. Case in point; in MSVC 2008, your E produces: E0(0), E1(-1), E2(0).
Geoff
As with all of this kind of behaviour people sometimes just assume that the compiler will do what is sensible. And of course, sensible is what *they* expect to happen.
Richard Corden