Enumerations in C++

An enumeration (also called enum) is a way to create a set of named integer constants. Instead of using plain numbers like 0, 1, 2, 3 in your code — which are hard to read — you give each number a meaningful name. Think of it like labeling the buttons on a TV remote: instead of pressing button number 2, you press the button labeled Volume Up.

Enums make code cleaner, more readable, and less error-prone. They are widely used to represent states, categories, directions, days of the week, and similar fixed sets of values.

Why Use Enumerations?

Imagine writing a program that handles traffic lights. Without enums:

int light = 0;  // 0 = RED, 1 = YELLOW, 2 = GREEN

A reader cannot tell what 0, 1, or 2 means without reading the comment. With enums:

enum Light { RED, YELLOW, GREEN };
Light current = RED;

Now the code is self-explanatory. RED means red — no comment needed.

Declaring an Enum

enum EnumName {
    VALUE1,
    VALUE2,
    VALUE3
};

By default, VALUE1 starts at 0, VALUE2 is 1, and so on. Each constant automatically gets the next integer value.

Basic Enum Example

#include <iostream>
using namespace std;

enum Day {
    MONDAY,    // 0
    TUESDAY,   // 1
    WEDNESDAY, // 2
    THURSDAY,  // 3
    FRIDAY,    // 4
    SATURDAY,  // 5
    SUNDAY     // 6
};

int main() {
    Day today = WEDNESDAY;
    cout << "Day number: " << today << endl;

    if (today == WEDNESDAY) {
        cout << "It's the middle of the week!" << endl;
    }
    return 0;
}

Output:

Day number: 2
It's the middle of the week!

Custom Values in Enums

You can assign specific integer values to enum constants. Constants after an assigned one continue incrementing from there.

#include <iostream>
using namespace std;

enum StatusCode {
    OK        = 200,
    NOT_FOUND = 404,
    ERROR     = 500
};

int main() {
    StatusCode response = NOT_FOUND;
    cout << "Response code: " << response << endl;
    return 0;
}

Output:

Response code: 404

Partial Assignment Example

enum Priority {
    LOW = 1,
    MEDIUM,    // automatically becomes 2
    HIGH,      // automatically becomes 3
    CRITICAL = 10
};

Using Enum in a Switch Statement

Enums work very well with switch statements because each case maps to a readable name instead of a plain number.

#include <iostream>
using namespace std;

enum Season { SPRING, SUMMER, AUTUMN, WINTER };

int main() {
    Season now = SUMMER;

    switch (now) {
        case SPRING: cout << "Flowers bloom." << endl; break;
        case SUMMER: cout << "It's hot outside." << endl; break;
        case AUTUMN: cout << "Leaves are falling." << endl; break;
        case WINTER: cout << "It's cold and snowy." << endl; break;
    }
    return 0;
}

Output:

It's hot outside.

Enum Class (Scoped Enum) — C++11

The older plain enum has a problem: its values leak into the surrounding scope. Two enums can accidentally share the same name, causing conflicts. C++11 introduced enum class (also called scoped enum) to fix this.

Problem with Plain Enum

enum Color { RED, GREEN, BLUE };
enum Fruit { APPLE, GREEN, MANGO };  // ERROR: GREEN already defined

Solution: enum class

#include <iostream>
using namespace std;

enum class Color { RED, GREEN, BLUE };
enum class Fruit { APPLE, GREEN, MANGO };   // no conflict now

int main() {
    Color c = Color::GREEN;
    Fruit f = Fruit::GREEN;

    if (c == Color::GREEN) {
        cout << "Color is green." << endl;
    }
    if (f == Fruit::GREEN) {
        cout << "Fruit is green (could be lime!)." << endl;
    }
    return 0;
}

Output:

Color is green.
Fruit is green (could be lime!).

With enum class, you must prefix each value with the enum name using ::. This prevents name collisions and makes code much clearer in large programs.

Diagram: Plain Enum vs Enum Class

Plain enum:
┌──────────────────────────────────────┐
│  enum Direction { UP, DOWN, LEFT }   │
│  Access: UP  (no prefix needed)      │
│  Risk: name clashes with other enums │
└──────────────────────────────────────┘

Scoped enum class:
┌──────────────────────────────────────────────┐
│  enum class Direction { UP, DOWN, LEFT }     │
│  Access: Direction::UP  (prefix required)    │
│  Safe: names stay inside enum scope          │
└──────────────────────────────────────────────┘

Changing the Underlying Type of Enum Class

By default, enum class values are stored as int. You can specify a different underlying type to save memory or match a specific data format.

enum class Direction : char {
    NORTH = 'N',
    SOUTH = 'S',
    EAST  = 'E',
    WEST  = 'W'
};

Converting Enum to Integer

A plain enum converts to int automatically. An enum class requires an explicit cast.

#include <iostream>
using namespace std;

enum class Level { BEGINNER, INTERMEDIATE, ADVANCED };

int main() {
    Level l = Level::ADVANCED;
    int val = static_cast<int>(l);
    cout << "Level value: " << val << endl;  // 2
    return 0;
}

Output:

Level value: 2

Real-World Enum Example: Game Character States

#include <iostream>
using namespace std;

enum class PlayerState {
    IDLE,
    RUNNING,
    JUMPING,
    ATTACKING,
    DEAD
};

void printState(PlayerState state) {
    switch (state) {
        case PlayerState::IDLE:      cout << "Player is standing still." << endl; break;
        case PlayerState::RUNNING:   cout << "Player is running." << endl; break;
        case PlayerState::JUMPING:   cout << "Player jumps into the air!" << endl; break;
        case PlayerState::ATTACKING: cout << "Player attacks the enemy." << endl; break;
        case PlayerState::DEAD:      cout << "Game Over." << endl; break;
    }
}

int main() {
    PlayerState current = PlayerState::JUMPING;
    printState(current);
    return 0;
}

Output:

Player jumps into the air!

Comparison: Plain Enum vs Enum Class

Featureenumenum class
ScopeGlobal (leaks into outer scope)Scoped (stays inside enum)
Name conflict riskHighNone
Implicit int conversionYesNo (needs static_cast)
Access styleVALUEEnumName::VALUE
Recommended for new codeNoYes

Key Takeaways

  • Enums let you define a set of named integer constants for cleaner code.
  • By default, enum values start at 0 and increment by 1.
  • You can assign custom integer values to any enum constant.
  • Enums pair naturally with switch statements for readable branching.
  • Prefer enum class over plain enum in modern C++ to avoid name collisions.
  • enum class values need an explicit cast to convert to int.

Leave a Comment

Your email address will not be published. Required fields are marked *