枚举为一组离散状态或选项提供类型安全的命名常量。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。

示例:状态码判断

C++ 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:聚合数据与默认访问权限的区别。