Enumerations

Location
  1. Courses

    /

  2. Complete C++ Course

    /

  3. The basics

    /

  4. Enumerations

What is an enumeration?

An enumeration is a type of variable that can only be assigned to a limited set of values. For example, an enumeration type named Difficulty could be limited to the values Easy, Medium and Hard.

Defining an enumeration type

We define an enumeration type by writing the keyword enum, then the name of the enumeration followed by the possible values (Separated by commas) a variable of that enumeration type can hold, inside braces {} ended with a semicolon ;.

Example:

enum Fruit {peach, apple, orange, banana};

We can then define a variable of type Fruit and assign it with any of the values defined in this enumeration.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream> enum Fruit {peach, apple, orange, banana}; int main() { Fruit fruit = peach; fruit = apple; if(fruit == apple) std::cout << "Apple" << std::endl; return 0; }

Specifying the value of the elements

The elements inside an enumeration have numerical values. They can be seen as constant variables. The following works:

if(apple == 1) std::cout << "Apple" << std::endl;

That also works:

if(fruit == 0) std::cout << "Peach" << std::endl;

This too:

int num = orange;

By default, the first element of an enumeration is set to 0, the next to 1, and so on. It is however possible to specify their values (at the definition of the enumeration):

enum Fruit {peach = 50, apple, orange = 12, banana};

In the enumeration above, apple equals 51 and banana 13 (When not specified, the value of an element is set to the value of the element before it plus 1).

A variable that is of an enumeration type simply represent a number, but it is limited to representing numbers that are defined inside the enumeration. So the following code would cause an error at compilation time:

1
2
3
4
5
6
7
8
9
10
#include <iostream> enum Fruit {peach = 50, apple, orange = 12, banana}; int main() { Fruit fruit = 123; // Error: Must be assigned with an element of the enumeration. return 0; }

Even if we assign the variable of enumeration type with a numerical value that is part of the enumeration, that will cause an error. It must be assigned with an element of the enumeration by using its name.

The following example will not compile successfully:

1
2
3
4
5
6
7
8
9
enum Fruit {peach = 50, apple, orange = 12, banana}; int main() { Fruit fruit = 50; // Error: Must be assigned with an element of the enumeration (By using its name). return 0; }

The following example works:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream> enum Fruit {peach = 50, apple, orange = 12, banana}; int main() { Fruit fruit = peach; if(fruit == 50) std::cout << "The variable fruit equals 50." << std::endl; /* "The variable fruit equals 50." is written in the console. */ return 0; }

Specifying the type of an enumeration

By default, an enumeration type is of type int. It is possible, in C++ only, to set the type of the enumeration. It must, however, be a signed or unsigned integral type. It is done by simply adding a colon : after the name of the enumeration, followed by the name of the type.

Here is an enumeration defined as an unsigned char:

enum Fruit : unsigned char{peach, apple, orange, banana};

Enumeration class

Using enumerations as we did above can be problematic. The name of the elements in the enumerations become used so we can not use them for other things (Name variables, functions...). Also, what if we define two enumerations and want both of them to have an element of the same name? That would not works.

enum Vegetable{carrot, cucumber, pepper}; enum Food{bread, soup, apple, pepper}; // Error: pepper has already been defined.

C++ has a feature that resolves that problem. That feature has been added to C++ in the version C++11, so if your compiler do no support that version, you will not be able to use it. Adding the keyword class after the keyword enum has the effect to make us have, in order to access an element, to use the name of the enumeration followed by two colons :: and then the name of the element.

The problem shown above is now resolved:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
enum class Vegetable{carrot, cucumber, pepper}; enum class Food{bread, soup, apple, pepper}; int main() { /* Now, there is no name collision, because both elements named pepper are accessed differently. */ Vegetable vegetable = Vegetable::pepper; Food food = Food::pepper; food = Food::soup; return 0; }

That kind of enumeration does not allow its elements to be used (directly) as if they were constant variables nor compare (directly) a variable of that enumeration type with a numerical value. The following would cause a compilation error:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream> enum class Food{bread, soup, apple, pepper}; int main() { if(Food::bread == 0) // Error, can not be compared to numbers. std::cout << "Equals 0." << std::endl; Food food = Food::soup; if(food == 1) // Error, can not be compared to numbers. std::cout << "Equals 1." << std::endl; if(food == Food::soup) // Works. std::cout << "It is a soup." << std::endl; return 0; }

There is a way to allow elements and variables of that kind of enumeration to be compared to numerical values (numbers), but we will see how to do that later.