Lesson 113 +10 XP

Scoped Enumerations (enum class)

Scoped Enumerations (enum class)

The scoped enumeration is built with the keyword class. It fixes the two traps of the unscoped enum: enumerators stay inside the type, and no implicit conversion to int happens.

Declaring one

#include <iostream>
using namespace std;

enum class Color {
  red,
  green,
  blue
};
  • Color is the new type.
  • red, green, blue are the enumerators, wrapped up inside Color.

Qualified names with ::

The enumerators appear only under the type name, so you must write two colons to name them:

int main() {
  Color c = Color::red;   // ok
  Color d = red;          // error: red is not in outer scope
  return 0;
}

Color::red is a qualified name - it says "red, but belonging to Color".

No implicit conversion to int

Color c = Color::green;
int n = c;   // ERROR: Color cannot silently become an int

The numbers underneath (0, 1, 2) still exist, but producing them costs your your explicit ask.

Convert with static_cast

When you really need the number, ask for it explicitly:

int n = static_cast<int>(Color::green);   // 1
Color back = static_cast<Color>(n);       // turns the int back

This also shows intent in the code - clear, auditable conversions.

Fewer collisions

Because enumerators live in the struct name, two different enums can reuse names without fighting:

enum class TrafficLight { red, yellow, green };
enum class Color { red, green, blue };   // no conflict

TL;DR

  • Declare with enum class Name { enumerators };.
  • Refer to enumerators with Color::red - the colon is required.
  • No implicit conversion to int; it is a compile error.
  • Convert explicitly with static_cast<int>(value).
  • Enumerator names do not leak, so collisions disappear.
  • Scoped enums are the safe, modern choice.