Basically, given
enum class Color : int { R, G, B };
Color c;
is there any way for c
to end up holding something other than R
, G
, B
? Or, in other words, an underlying int
other than 0
, 1
, or 2
?
I know that the declaration of c
above leaves it uninitialize, and that
Color c{};
would initialize it to R
/0
.
However, I've discovered that if the definition of the enumeration were
enum calss Color : int { R = 1, G, B };
then the {}
-initialized c
would have value 0
, which does not correspond to any of R
/G
/B
(I've verified that c == Color::enumerator
returns false
for any enumerator
chosen from R
, G
, B
; and static_cast<int>(c)
is 0).
Now this, looks a bit edgy to me: if 0
does not underlay any of the enumerators, then why does {}
-initialization give that value to the underlaying int
?
CodePudding user response:
Color
is a scoped enumeration type, therefore its underlying type is fixed. (In your case you have explicitly specified it as int
, but scoped enumerations also default to int
when not explicitly specified. You can also explicitly specify an underlying type for unscoped enumerations.)
For an enumeration whose underlying type is fixed, all values of the underlying type are valid values for the enumeration. That is, Color
can hold any int
value. If it holds a value that none of its enumerators have, that just means that it won't compare equal to any of its enumerators. This may seem a bit strange, but the alternative would have been to give the program undefined behaviour, and most people would agree that we don't need any more undefined behaviour in C .
(For an enumeration whose underlying type is not fixed, the rules are a bit more complicated. It is usually still possible to give them values that don't correspond to any enumerator, but the range of allowable values is narrower. Going outside that range results in undefined behaviour.)
CodePudding user response:
c
gets the value of zero because using {}
value intialiazes c
and for built in types (which is what underlies the enumeration) that is always zero initialization.
You can also manually assign a value that is not in the list of enumerations by using static_cast
like
c = static_cast<Color>(42);