← Back to C++ Course | Chapter 8: OOP Core | Lesson 14 of 14

C++ Enums

An enum is a fixed list of named choices, like days of the week or traffic light colors. It stops you from using values that are not on the list.
Syntax
cpp
enum EnumName { VALUE_ONE, VALUE_TWO, VALUE_THREE };

EnumName variable_name = VALUE_ONE;

What Is an Enum?

An enum defines a type whose values are restricted to a small named set, like Color { RED, GREEN, BLUE }, making code that models a fixed set of options far more readable than using raw integers with unclear meaning.

Under the hood each enumerator is stored as an integer, starting at 0 by default and incrementing for each following name.

Example: What Is an Enum?

cpp
// Include std::cout and std::cin
#include <iostream>

enum Color { RED, GREEN, BLUE };

// Program execution starts in main()
int main() {
	Color c = GREEN;
	// Print to the console with cout
	std::cout << c << std::endl;
	// Return 0 to signal that the program finished successfully
	return 0;
}

Plain Enums and Their Pitfalls

A plain enum implicitly converts to int and its enumerator names leak into the surrounding scope, which means two plain enums in the same scope can't reuse a name like RED without a naming collision.

This looseness also lets you accidentally compare or assign values from unrelated enums, since the compiler doesn't stop the implicit int conversion.

Example: Plain Enums and Their Pitfalls

cpp
#include <iostream>

enum Color { RED, GREEN, BLUE };

int main() {
	int x = RED; // implicitly converts to int
	std::cout << x << std::endl;
	return 0;
}

Enum Class for Type Safety

enum class (C++11+) scopes its enumerators inside the enum's own name (Color::RED) and does not implicitly convert to int, so mixing up two different enum types becomes a compile error instead of a silent bug.

This is why modern C++ style strongly prefers enum class over the plain, unscoped enum in new code.

Example: Enum Class for Type Safety

cpp
#include <iostream>

enum class Color { RED, GREEN, BLUE };

int main() {
	Color c = Color::RED; // scoped, no implicit int conversion
	std::cout << (c == Color::RED) << std::endl;
	return 0;
}

Setting the Underlying Type

By default an enum's underlying integer type is implementation-defined, but you can pin it explicitly, e.g. enum class Status : uint8_t, to control the type's storage size, which matters when the enum is part of a struct laid out for a specific memory footprint or serialized format.

Example: Setting the Underlying Type

cpp
#include <iostream>
#include <cstdint>

enum class Status : uint8_t { Active, Inactive }; // explicitly pinned type

int main() {
	Status s = Status::Active;
	std::cout << static_cast<int>(s) << std::endl;
	return 0;
}

Enums in Switch Statements

Enums pair naturally with switch statements, since the small closed set of values makes it easy for both the programmer and the compiler to reason about every possible case; many compilers will even warn you if a switch on an enum class doesn't handle every enumerator.

Example: Enums in Switch Statements

cpp
// Include std::cout and std::cin
#include <iostream>

enum class Color { RED, GREEN, BLUE };

// Program execution starts in main()
int main() {
	Color c = Color::GREEN;
	// Choose a branch based on the value of c
	switch (c) {
		case Color::RED: std::cout << "Red" << std::endl; break;
		case Color::GREEN: std::cout << "Green" << std::endl; break;
		case Color::BLUE: std::cout << "Blue" << std::endl; break;
	}
	// Return 0 to signal that the program finished successfully
	return 0;
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Using a plain enum whose names leak into the surrounding scope and clash with other names.
  2. Assuming an enum class converts implicitly to int, when you need static_cast<int>(value).
  3. Expecting cout << color to print the enumerator name, when it prints its integer value.
Chapter Summary
  • Classes and objects bundle data and methods, with access specifiers controlling visibility.
  • Constructors, destructors, the copy constructor, and the this pointer manage how objects are created, copied, and destroyed.
  • Static members, friend functions, operator overloading, structures, and enums extend what classes can do.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.