C++ Enums

An enum is a user-defined type whose values are a fixed set of named constants. Enums make code more readable when a variable should hold one choice from a small list, such as a direction, status, mode, or menu option.

C++ has traditional unscoped enums written with enum, and scoped enums written with enum class. Modern C++ code usually prefers enum class because it avoids name conflicts and prevents accidental integer conversions.

Basic Enum Syntax

A traditional enum lists its possible values inside braces. Each listed name represents an integer constant, starting at 0 by default unless you choose specific values.

#include <iostream>

enum Direction {
    North,
    East,
    South,
    West
};

int main(void) {
    Direction heading = East;

    if (heading == East) {
        std::cout << "Moving east" << std::endl;
    }

    std::cout << "Numeric value: " << heading << std::endl;

    return 0;
}

Output:

Moving east
Numeric value: 1

Here, North has value 0, East has value 1, and so on. The variable heading can store one of the named Direction values.

Choosing Explicit Values

You can assign values yourself when the numbers matter, such as when matching file formats, network codes, or an existing API. If a later name does not specify a value, it continues from the previous value.

#include <iostream>

enum HttpStatus {
    Ok = 200,
    Created = 201,
    BadRequest = 400,
    NotFound = 404
};

int main(void) {
    HttpStatus status = NotFound;

    std::cout << "Status code: " << status << std::endl;

    return 0;
}

Output:

Status code: 404

Explicit values are useful, but avoid depending on the numeric value unless it is part of the program’s real meaning. In many programs, the names are the important part.

Scoped Enums With enum class

A scoped enum keeps its enumerator names inside the enum type. You must write the type name, such as TrafficLight::Red, which makes the code clearer and prevents unrelated enums from reusing the same names in a confusing way.

#include <iostream>

enum class TrafficLight {
    Red,
    Yellow,
    Green
};

int main(void) {
    TrafficLight light = TrafficLight::Green;

    switch (light) {
        case TrafficLight::Red:
            std::cout << "Stop" << std::endl;
            break;
        case TrafficLight::Yellow:
            std::cout << "Prepare" << std::endl;
            break;
        case TrafficLight::Green:
            std::cout << "Go" << std::endl;
            break;
    }

    return 0;
}

Output:

Go

enum class values do not automatically behave like integers. If you need the underlying number, convert explicitly with static_cast.

#include <iostream>

enum class Priority {
    Low = 1,
    Medium = 2,
    High = 3
};

int main(void) {
    Priority taskPriority = Priority::High;

    std::cout << "Priority level: "
              << static_cast<int>(taskPriority)
              << std::endl;

    return 0;
}

Output:

Priority level: 3

When To Use Enums

Use an enum when a value should come from a known, limited set. For example, enum class FileState { Open, Closed, Error }; is clearer than using arbitrary integers such as 0, 1, and 2.

Prefer enum class for new C++ code. Use a traditional enum mainly when you are working with older code or an API that expects unscoped enum values.

Common Mistakes

  • Forgetting the semicolon after the enum definition.
  • Expecting enum class values to print directly like integers.
  • Using plain integers when named enum values would make the code easier to understand.
  • Creating two unscoped enums with the same enumerator names in the same scope.

Takeaway: enums give names to a fixed set of choices, and enum class is the safer default for modern C++ programs.