Scoped enum class
Type-safe enumerations.
Scoped enum class is a free C++ Academy lesson on CoddyKit. This is lesson 1 of 4. Any 3 lessons of this learning path are free to read in full — after that, CoddyKit PRO unlocks every lesson, plus hands-on practice with a built-in code editor and a 24/7 AI tutor. It is part of the C++ Academy learning path, and your progress syncs across the web and the CoddyKit app. The C++ Academy course includes 4 lessons in total.
Plain Enums Leak Names
A classic C-style enum dumps its names into the surrounding scope and silently converts to int. That makes name clashes and accidental comparisons easy.
- enum class fixes both problems.
- Values are scoped and strongly typed.
#include <iostream>
enum Color { Red, Green, Blue };
int main() {
Color c = Green;
int x = c; // implicit conversion to int
std::cout << x << "\n";
}Declaring a Scoped Enum
Add the class (or struct) keyword to make a scoped enumeration. Now you must qualify each value with the enum name.
#include <iostream>
enum class Color { Red, Green, Blue };
int main() {
Color c = Color::Green;
if (c == Color::Green) std::cout << "green\n";
}No Implicit Conversion
A scoped enum will not implicitly turn into an int. This prevents bugs where an enum is used in arithmetic by accident.
- To get the number you must cast explicitly.
#include <iostream>
enum class Color { Red, Green, Blue };
int main() {
Color c = Color::Blue;
int n = static_cast<int>(c); // explicit
std::cout << n << "\n"; // prints 2
}Underlying Type
By default the underlying type is int, but you can choose a smaller or specific integer type to save space or match a protocol.
#include <iostream>
#include <cstdint>
enum class Status : std::uint8_t { Ok = 0, Warn = 1, Error = 2 };
int main() {
Status s = Status::Warn;
std::cout << static_cast<int>(s) << "\n";
}Custom Values
You can assign explicit values to enumerators. Values that follow an explicit one continue counting from it.
#include <iostream>
enum class Http { Ok = 200, NotFound = 404, ServerError = 500 };
int main() {
Http h = Http::NotFound;
std::cout << static_cast<int>(h) << "\n";
}Switching on an Enum
Enums shine inside switch statements. Listing every case makes the intent clear and lets the compiler warn about missing cases.
#include <iostream>
enum class Dir { North, East, South, West };
const char* name(Dir d) {
switch (d) {
case Dir::North: return "N";
case Dir::East: return "E";
case Dir::South: return "S";
case Dir::West: return "W";
}
return "?";
}
int main() { std::cout << name(Dir::East) << "\n"; }Enums as Function Arguments
Passing a scoped enum communicates intent far better than passing a bare int or bool. The compiler enforces that only valid enum values are used.
#include <iostream>
enum class Align { Left, Center, Right };
void render(const char* text, Align a) {
std::cout << text << " aligned " << static_cast<int>(a) << "\n";
}
int main() { render("Hi", Align::Center); }Comparing Enum Values
Scoped enums support == and != directly. Relational operators (<, >) also work because the values are ordered.
#include <iostream>
enum class Level { Low, Medium, High };
int main() {
Level l = Level::High;
std::cout << (l > Level::Low ? "above low\n" : "low\n");
}Iterating Conceptually
Enums do not iterate automatically, but a common pattern is to cast through the underlying integers. Keep a sentinel like Count to know the range.
#include <iostream>
enum class Coin { Penny, Nickel, Dime, Count };
int main() {
for (int i = 0; i < static_cast<int>(Coin::Count); ++i)
std::cout << i << " ";
std::cout << "\n";
}Why Type Safety Matters
Two unrelated scoped enums can never be accidentally mixed, even if both have a value named None. The compiler treats them as distinct types.
#include <iostream>
enum class Fruit { None, Apple };
enum class Tool { None, Hammer };
int main() {
Fruit f = Fruit::None;
// Tool t = f; // would NOT compile
std::cout << (f == Fruit::None) << "\n";
}When to Use Plain Enums
Plain enums still appear in legacy APIs and bit-flag code where implicit int conversion is convenient. For new code, prefer enum class unless you have a specific reason.
Quick Check
Test your understanding of scoped enums.
Recap
You learned scoped enums:
enum classscopes values and blocks implicit int conversion.- Use
static_cast<int>to read the number. - Choose an underlying type with
: type. - Prefer
enum classfor type-safe, self-documenting code.
Learn C++ with an AI tutor — free
Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.
- Courses
- 51
- Lessons
- 203
Frequently Asked Questions
Is the “Scoped enum class” lesson free?
Yes — any 3 lessons of the C++ Academy learning path, including “Scoped enum class”, are free to read in full here on the web. After that, CoddyKit PRO unlocks every lesson, plus interactive practice with a built-in code editor and a 24/7 AI tutor. The C++ Academy course includes 4 lessons in total.
What will I learn in “Scoped enum class”?
Type-safe enumerations. You practise C++ Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start C++ Academy?
No prior experience is required. C++ Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 1 of 4.
How long does the “Scoped enum class” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this C++ Academy lesson?
Yes. Every C++ Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Scoped enum class
- Unions and Their Risks
- std::variant
- std::visit