第2.16章: enum class

English

什么是 enum class

enum class(有作用域枚举)定义了一组有名字的常量, 它们是强类型的,并且带有作用域。 枚举值不会泄漏到外围作用域,也不会隐式转换为整数或其他枚举类型。


enum class Color { Red, Green, Blue };

// Declaration and comparison without leaking names
Color c{Color::Red};
bool is_red{c == Color::Red};

指定底层类型

你可以指定底层的存储类型。若省略,则默认为 int。


enum class Status : unsigned char { Ok, Warning, Error };

// Declaration using the underlying storage
Status s{Status::Error};

与底层整数类型之间的转换

enum class 不会隐式转换为整数。请使用显式转换:


#include <utility>      // ::std::to_underlying
#include <type_traits>  // ::std::underlying_type_t

enum class ErrorCode { None, Minor, Major };

// To integer
auto v1{::std::to_underlying(ErrorCode::Major)};
auto v2{static_cast<::std::underlying_type_t<ErrorCode>>(ErrorCode::Major)};

// Back to enum
ErrorCode e1{static_cast<ErrorCode>(v1)};
ErrorCode e2{static_cast<ErrorCode>(v2)};

bool ok1{e1 == ErrorCode::Major};
bool ok2{e2 == ErrorCode::Major};

这些整数值可用于算术、位运算、存储或互操作。当你需要语义上的清晰时,再转换回枚举类型。

用 using enum 把枚举值引入作用域

通过 using enum,你可以把某个枚举的所有值引入当前作用域,从而无需限定即可使用它们。


enum class Color { Red, Green, Blue };

Color a{Color::Green};

// Bring all Color values into scope
using enum Color;

Color b{Blue};         // No need to write Color::Blue
bool is_green{a == Green};

请注意可读性。using enum 减少了冗长,但同时也隐藏了枚举名。 只在它明显提升清晰度的地方使用(例如局部作用域或简短的类 switch 逻辑)。

枚举的算术与位运算

进行算术与位运算时,请把枚举值转换为它们的底层整数类型。 显式地定义标志或掩码,然后用整数进行计算。


#include <utility>

enum class Permission : unsigned {
  Read    = 1u,
  Write   = 2u,
  Execute = 4u
};

using enum Permission; // bring Read, Write, Execute into scope

// Build a mask from enum values via underlying integers
unsigned mask{::std::to_underlying(Read) | ::std::to_underlying(Write)};

// Test a flag
bool has_write{(mask & ::std::to_underlying(Write)) != 0u};

// Add a flag
mask |= ::std::to_underlying(Execute);

// Remove a flag
mask &= ~::std::to_underlying(Read);

// Store and restore from an integer
Permission p_exec{static_cast<Permission>(::std::to_underlying(Execute))};
bool is_exec{p_exec == Execute};

避免直接对枚举值做算术运算。始终在底层整数上操作,并在适当的地方转换回枚举。

要点