Enumerations

The most basic user-defined type is an enumeration. Enumerations allow us to create variables whose values are restricted to a set of options called enumerators.

Table of Contents

  1. Why Enumerations
  2. Defining and Using Enums
  3. Printing Out Enums
  4. C-Style Enums
  5. Further Reading

Why Enumerations

Enumerations help us remove magic numbers from our code.

They also help us avoid using old school #define constants, which don’t follow scope and type rules.

In general they lead to more readable and more intention revealing code.

Defining and Using Enums

Let’s define an enumeration for the days of the week:

enum class Day { mon, tue, wed, thu, fri, sat, sun };

We can now create a variable of type Day and assign it one of seven possible enumerators:

Day today = Day::sat;

💡 Best Practice:

Don’t use ALL_CAPS when naming your enum options.

Printing Out Enums

Internally the enumerators are stored as auto-incrementing ints. These integers are meant for internal use only. We cannot std::cout an enum variable unless we use an explicit cast:

enum class Direction { north, south, east, west };

Direction doorPosition = Direction::north;

std::cout << doorPosition; // Error!
std::cout << static_cast<int>(doorPosition);    // Outputs: 0
std::cout << static_cast<int>(Direction::west); // Outputs: 3

C-Style Enums

Sometimes called “plain” enums, you might encounter these older style enums defined like this:

  enum directions {NORTH, SOUTH, EAST, WEST}; // Was convention to use ALL_CAPS.
  enum playerDirection = NORTH; // Notice the option isn't scoped to the enum!

Behind the scenes each of the enum choices is assigned an integer value starting at 0. Although those values can also be explicitly set:

  enum directions {NORTH = 5, SOUTH = 10, EAST = 15, WEST = 20};

💡 Best Practice:

Avoid C-Style enums as they aren’t well-scoped and can lead to naming collisions.

Further Reading