Scoped enum class
Type-safe enumerations.
Scoped enum class is a free C++ Academy lesson on CoddyKit — lesson 1 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the C++ Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
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.
Frequently asked questions
Is the “Scoped enum class” lesson free?
Yes — the full text of “Scoped enum class” is free to read here on the web, and the C++ Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the C++ Academy course, upgrade to CoddyKit PRO.
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; this is — lesson 1 of 4, so you can start here or from the beginning and move at your own pace.
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