CSE 202: Computer Science II, Winter 2018
Enumerations

Sometimes it is desirable to use an integral type for representing a finite range of values; for example, one can declare int color, but instead of using it for representing an integer, it represents a color with the agreed upon values: 0 being black, 1 being blue, 2 being green, 3 being yellow, and so on.

In C++, the enumeration enables one to create named constants associated with one integral type so that, for example, you do not need to remember the value associated with each color if you are trying to represent a color.

In the following example, the enumeration named color is declared with 8 enumerators and the enumeration variable c is declared with an initial value set to the value of the yellow enumerator.

enum color { black, blue, green, yellow, cyan, white, magenta, red }; color c = yellow;

Strictly speaking, color is not a user-defined type (like a class is); all enumerations have an underlying type which will always be an integral type. This integral type will not necessarily be int, it might be short int, the underlying type used for each enumeration declaration is implementation defined.

Because all enumerations are based on an integral type, they are implicitly convertable to their integral type; thus you can see the value of an enumerator by inserting an enumeration object into an output stream like std::cout. The enumerator yellow, in the above example, has an integral value of 3.

Each enumerator inside of an enumeration is associated with a distinct integral value. By default, the first enumerator is associated with the value 0 and each proceeding enumerator is associated with the value of the preceeding enumerator plus 1. Therefore, our color enumeration has the following values:

One can associate different values to the enumerators by using an initializer on one or more enumerator definitions:

enum color { black = 0x000000, blue = 0x0000ff, green = 0x008000, yellow = 0xffff00, cyan = 0x00ffff, white = 0xffffff, magenta = 0xff00ff, red = 0xff0000 };

Now, all of the colors have values in accordance with the RGB color model; their values are expressed as hexadecimal integer literals. One does not need to use an initializer on every enumerator, in which case, each proceeding enumerator that does not have an initializer will be associated with the value of the previous enumerator plus one.

Here's another enumeration example:

struct card { enum rank_type { ace = 1, two, three, four, five, six, seven, eight, nine, ten, jack, queen, king }; enum suit_type { clubs, diamonds, hearts, spades }; rank_type rank; suit_type suit; }; card c = { card::ace, card::spades };

rank_type and suit_type are now nested types of card. The enumerators are also within the scope of card. card is an aggregate and can be initialized with an initializer list containing the enumerator values for rank and suit.