枚举为一组离散状态或选项提供类型安全的命名常量。C++ 推荐 enum class:枚举量写在枚举类型作用域内(如 Status::Ok),不会与外围整型或宏意外混用,也不能不经转换就与 int 比较。本节说明 enum class 与老式 enum 的差异、底层整型,以及怎样用 if / switch 判断枚举值;switch 的一般写法见条件分支。
enum class 与老式 enum
下列声明定义三种状态;未赋值的成员从前一项加 1 递增(Ok 为 0,Warning 为 1,Error 为 2):
enum class Status { Ok, Warning, Error };比较与赋值须写全名:s == Status::Error,不能写 s == 2(除非显式 static_cast)。老式 enum Color { Red, Green }; 的枚举常量会泄漏到外围作用域,易与同名标识冲突,新代码宜默认 enum class。
示例:状态码判断
#include <iostream>
#include <type_traits>
enum class Status { Ok, Warning, Error };
Status check(int code) {
if (code == 0) {
return Status::Ok;
}
if (code < 0) {
return Status::Error;
}
return Status::Warning;
}
int main() {
Status s = check(-1);
if (s == Status::Error) {
std::cout << "failed\n";
}
using U = std::underlying_type_t<Status>;
std::cout << "Error as int: "
<< static_cast<U>(Status::Error) << '\n';
return 0;
}输出:
failed
Error as int: 2与 C 枚举不同,enum class 不能直接与 int 比较或赋值;需要底层整型时须显式 static_cast,避免无意混用魔法数字。
手动指定枚举值
可为部分成员指定整数值,未指定的成员取前一成员值加 1(规则与 C 语言枚举 相同):
enum class HttpCode : int {
Ok = 200,
NotFound = 404,
ServerError = 500
};
enum class Flag { A = 1, B = 2, C }; // C 为 3各常量须为整数类型;若业务仍使用裸整数而不用枚举名,可读性优势会减弱。
指定底层类型
默认底层类型为实现定义的整型(通常足以表示所有枚举常量)。需要紧凑存储或与协议字段对齐时可显式指定:
enum class Byte : unsigned char { Zero = 0, Max = 255 };| 形式 | 作用 |
|---|---|
enum class E { ... }; | 强类型,作用域为 E:: |
enum class E : T { ... }; | 指定底层类型 T(须为整型) |
enum E { ... };(传统) | 常量进入外围作用域,可隐式转 int |
传统 enum
enum Color { Red, Green, Blue };
Color c = Green;
int n = Green; // 允许:隐式转为 int,值为 1遗留代码与部分 C 接口中常见;新代码更推荐 enum class。若需与只接受 int 的旧 API 交互,可对传统枚举或经 static_cast 转换的 enum class 做封装。
在 switch 与类中使用
switch 可直接对 enum class 分支,编译器可检查是否覆盖所有枚举量(配合 [[fallthrough]] 等现代写法):
switch (s) {
case Status::Ok:
std::cout << "ok\n";
break;
case Status::Warning:
std::cout << "warn\n";
break;
case Status::Error:
std::cout << "err\n";
break;
}类内定义枚举可避免与全局名冲突,并与类与对象的状态字段配合:
class Connection {
public:
enum class State { Closed, Open, Error };
State state() const { return state_; }
private:
State state_ = State::Closed;
};典型用途
- 状态机:描述连接、任务、UI 的离散状态。
- 错误码:为返回值赋予统一命名,便于日志与排查。
- 菜单与选项:将用户输入映射为有意义的标识。
- 标志位组合:简单标志可用枚举;大量位标志可考虑
std::bitset或具名常量。
本节说明了 enum class 与传统 enum 的语法、底层类型及使用场景。下一节介绍结构体与 class:聚合数据与默认访问权限的区别。