Concepts / Enumerators and Their Values in C++

Enumerators and Their Values in C++

Whenever you read an enumerator in code, the qualified name tells you which enumerator it is. Follow the qualifier before the :: rather than the bare word red.

  • Programming

Two Different Things Called red

Imagine you are building a small program that tracks two things: the color of a paint sample and the state of a traffic light. Both sets of choices seem to need a word called red. It is tempting to believe that red is simply red, one fixed thing that means the same everywhere in the program. This belief is the misconception this article addresses.

What do you think happens?

Two enum classes are declared: one named Color with red, blue, and green, and one named Traffic_light with green, yellow, and red. Are Color::red and Traffic_light::red the same enumerator, or two separate enumerators that share a spelling?

  • They are the same enumerator

  • They are two separate enumerators that happen to share the spelling red

Reveal answer
Answer:

They are two separate enumerators that happen to share the spelling red.

Enumerators are in the scope of their enum class, so the same name can appear in different enum classes without confusion. The enum class name in the qualified name tells you which enumerator is meant.

Keep this prediction in mind. The rest of the article traces how C++ decides which red a given line of code means.

Why the Same Spelling Does Not Clash

The source gives the reason for this design directly. Because enumerators such as red are in the scope of their enum class, they can be reused in different enum classes without confusion. Reusing the word red does not force the programmer to invent a new spelling such as colorRed or lightRed. Each enum class keeps its own list, and the qualified name tells the compiler which list you mean.

A helpful way to picture this is as containers. Each enum class is a container that holds its own enumerators. The word red appears inside the Color container and again inside the Traffic_light container. Those are two entries in two different places, and the container that holds each one is what distinguishes them.

Colorenum classredColor::redTraffic_lightenum classblueColor::bluegreenColor::greengreenTraffic_light::greenyellowTraffic_light::yellowredTraffic_light::redcontainscontainscontainscontainscontainscontains
Both enum classes contain a red enumerator. The two entries are separate because each one sits inside a different enum class.

Declaring an enum class

Definition

An enum class declares a named set of enumerators inside braces. It is written with the keywords enum class, followed by a name, and then a braced list of enumerators separated by commas.

cpp
Notes on the code
  • enum class: the keywords that start the declaration
  • Color: the name of the enum class
  • { red, blue, green }: the braced list of enumerators
  • The commas separate the enumerators, and the semicolon ends the declaration

The declaration above creates three enumerators: red, blue, and green. Each one belongs to the Color enum class. The source also declares a second enum class with the same kind of structure: enum class Traffic_light { green, yellow, red };. The two lists are independent, so Color and Traffic_light each keep their own set of names.

Colorenum class name::scope operatorredenumerator namefollowed byselects
The name Color::red is built from three parts. The enum class name comes first, the scope operator follows, and the enumerator name comes last.

Reading a Qualified Name

To use an enumerator, you write the enum class name, the scope operator ::, and the enumerator name. The source uses the following line to create a variable of type Color and set it to the red enumerator.

cpp
Notes on the code
  • Color on the left: declares that the variable col has type Color
  • Color::red on the right: names the specific red enumerator inside Color

The name Color on the left declares the variable type. The name Color::red on the right names one particular enumerator. Read the qualifier before the :: as the question of which list you are looking in. Only after that does the bare word red pick out an entry.

Key point

Whenever you read an enumerator in code, the qualified name tells you which enumerator it is. Follow the qualifier before the :: rather than the bare word red.

Tracing Both Enum Classes Together

cpp
Notes on the code
  • The first two lines declare two independent enum classes
  • The last two lines each create a variable and set it using a qualified name
Worked example

Tracing which red each line means

In the program above, which enumerator does Color::red refer to, and which enumerator does Traffic_light::red refer to?

  1. 1
    Find the qualifier

    In Color::red, the qualifier is Color. In Traffic_light::red, the qualifier is Traffic_light.

  2. 2
    Look inside that enum class

    Color::red looks only in the list { red, blue, green }. Traffic_light::red looks only in the list { green, yellow, red }.

  3. 3
    Select the matching entry

    Each list contains a red entry, and the qualifier chooses which one is meant.

  4. 4
    Compare the two results

    The two results are separate enumerators. They share a spelling but belong to different enum classes.

Result

Color::red is the red enumerator of Color, and Traffic_light::red is the red enumerator of Traffic_light. They are different enumerators, even though both are spelled red.

Where One Enum Class Ends

The braces of an enum class mark its scope. The names listed between the braces belong to that enum class and are visible through its qualified names. In the program above, the braces of Color hold red, blue, and green, and the braces of Traffic_light hold green, yellow, and red. When a line of code is outside those braces, the bare names inside them are not what the line refers to; the line refers to them through the enum class name.

Mistakes Beginners Make with Qualified Names

  • Common mistake

    Assuming red is one fixed thing that means the same everywhere

    What it looks like

    Reading the line Traffic_light light = Traffic_light::red; and thinking it refers to the same value as Color::red.

    Why it fails

    Each enum class has its own list, and the two red entries are separate enumerators.

    Do this instead

    Read the qualifier first and identify which enum class owns the name.

  • Common mistake

    Tracing a program by stopping at the bare word red

    What it looks like

    Following a trace through the line Color col = Color::red; and writing down just red without the Color qualifier.

    Why it fails

    A trace that stops at red and forgets Color or Traffic_light is where the misconception usually causes a wrong conclusion.

    Do this instead

    Keep the full qualified name, including the enum class name and the :: operator, in every step of the trace.

  • Common mistake

    Inventing new spellings to avoid a clash

    What it looks like

    Renaming the traffic light entry to lightRed so that it does not match the color entry.

    Why it fails

    Enumerators in different enum classes do not clash, so the renaming is unnecessary.

    Do this instead

    Reuse the natural name and rely on the qualified name to tell the enumerators apart.

Checking Your Reading of Qualified Names

EASY

Given the two enum classes enum class Color { red, blue, green }; and enum class Traffic_light { green, yellow, red };, state which enumerator each of these names refers to: Color::green, Traffic_light::green, and Traffic_light::red. Explain your answer by pointing to the qualifier in each name.

Hints
  • Look at the word before the :: first.
  • Check which braced list contains the bare name that follows the ::.
MEDIUM

Write two lines of code that declare a variable of type Color and a variable of type Traffic_light, and set each one to its red enumerator. Then write one sentence explaining why the two red values do not clash.

Hints
  • Use the pattern Type name = Type::enumerator; for each variable.
  • The sentence should mention the scope of each enum class.

Key Takeaways

  • An enum class declares a named set of enumerators inside braces, such as enum class Color { red, blue, green };
  • Enumerators are in the scope of their enum class, so the same name, such as red, can appear in different enum classes without confusion.
  • Color::red and Traffic_light::red are different enumerators, even though both are spelled red.
  • To read or trace an enumerator, follow the qualifier before the :: and keep the enum class name with the enumerator name.

Related concepts

More concepts starting with E