std::to_underlying是c++23新增函数,需编译器支持(msvc 17.5+/gcc 13+/clang 16+)并启用-std=c++23;仅适用于显式指定底层类型的枚举(如enum class e : int),返回精确底层类型值,等价于static_cast但更类型安全、语义明确。

std::to_underlying 是 C++23 新增的工具,不是所有编译器都支持
如果你在 g++ 或 clang++ 下编译失败,大概率是因为标准未启用或版本太低。它要求 C++23 支持,且目前 MSVC 2022 17.5+、GCC 13+、Clang 16+ 才提供该函数。启用方式必须显式指定:-std=c++23(GCC/Clang)或 /std:c++23(MSVC)。漏掉这个标志,即使头文件包含 <utility></utility>,也会报 ‘to_underlying’ is not a member of ‘std’。
用法很简单,但只能作用于有固定底类型(fixed underlying type)的枚举
std::to_underlying 只接受 enum 或 enum class 的值,且该枚举必须声明了底层类型(如 enum E : int 或 enum class E : uint8_t)。普通无底层类型声明的 enum(如 enum E { A, B };)在某些编译器下可能通过,但行为未定义——C++ 标准只要求对“有固定底层类型”的枚举保证安全转换。
- ✅ 正确:
enum class Color : uint8_t { Red, Green, Blue };→std::to_underlying(Color::Green) - ❌ 危险:
enum Status { OK, ERROR };→ 编译可能通过,但底层类型由编译器决定,std::to_underlying不保证可移植
替代方案:C++20 及更早版本怎么安全取值
如果不能用 C++23,别硬套 static_cast 直接转——尤其对 enum class,会因类型不匹配编译失败。常见写法是加一层 static_cast 到其底层类型:
enum class Flag : int { Off = 0, On = 1 };
auto val = static_cast<:underlying_type_t>>(Flag::On);</:underlying_type_t>
注意:std::underlying_type_t<t></t> 要求 T 是枚举类型,否则 SFINAE 失败;若不确定是否为枚举,可用 std::is_enum_v<t></t> 静态断言保护。
和传统 static_cast 比,std::to_underlying 优势在哪
核心不是功能差异,而是语义明确 + 类型安全增强:
- 它只接受枚举类型,传入
int或指针会直接编译失败,避免误用 - 返回类型是
std::underlying_type_t<e></e>,而非裸int,保留底层类型信息(比如enum : uint16_t返回uint16_t,不是int) - 在模板中更易推导,例如
auto x = std::to_underlying(e);的类型可直接用于位运算或数组索引,无需额外using声明
不过性能完全等价——它就是个内联 static_cast 封装,没有运行时开销。
真正容易被忽略的是:哪怕用了 C++23,也得确保枚举带底层类型声明,否则看似能编译,实则依赖实现,跨平台时可能出错。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











