enum class 比普通 enum 更安全:作用域隔离、无隐式转换、支持前向声明、避免 ADL 干扰、强制显式底层类型控制,新代码应默认使用。
普通 enum 定义时,枚举值会直接注入到外层作用域,容易引发

enum class(即强类型枚举)则将所有枚举值封装在枚举名的作用域内,必须通过作用域解析符访问。
示例对比:
enum Color { Red, Green, Blue }; // Red 可直接使用
enum class Status { OK, Error, Pending }; // Status::OK 才能使用
Color 的值隐式转换为 int,可直接参与算术或比较(如 Red + 1)Status 的值不能隐式转为整数,必须显式 static_cast(Status::OK)
enum { OK }),普通 enum 会编译报错,enum class 不会两者都支持显式指定底层类型(如 uint8_t),但普通 enum 的底层类型由编译器自动推导(通常是 int),而 enum class 必须显式声明才能控制内存占用或 ABI 兼容性。
enum class 默认底层类型是 int,但某些平台或序列化场景需要固定宽度(如网络协议中用 uint16_t)enum class FileMode : uint8_t { Read = 1, Write = 2 };
enum 加底层类型需 C++11 起支持:enum LogLevel : uint32_t { Debug, Info, Warn };
enum class 无法用 sizeof 预判大小(依赖编译器实现),可能影响结构体对齐普通 enum 的枚举值暴露在外层作用域,可能意外触发 ADL,导致函数重载解析异常;enum class 完全避免该问题。
void foo(int) 和 void foo(Color),调用 foo(Red) 会匹配 Color 版本;但若某处有 using namespace std; 且 std::swap 被 ADL 拉入,普通 enum 值可能干扰 swap 查找enum class 枚举值不会参与 ADL,调用 swap(a, b) 时只看 a、b 类型本身,更可控enum 容易因同名值(如 Success)引发 ODR 违规或链接错误除非维护遗留 C 接口或受限于旧编译器(如 VS2012 以前),新代码应默认使用 enum class。以下情况尤其不能妥协:
if (status == 0) 这类模糊判断)enum class Status; 合法,普通 enum Status; 不合法)constexpr 枚举值做模板非类型参数(C++20 起,仅 enum class 支持完整 constexpr 行为)真正棘手的地方在于:普通 enum 的隐式转换看似方便,实则掩盖了类型意图;而 enum class 多写的几个 :: 和 static_cast,换来的是一致性和可维护性——这点在跨模块协作时尤为明显。