std::is_scoped_enum是c++23引入的编译期类型特征,用于判断类型是否为enum class或enum struct定义的作用域枚举;对普通enum、非枚举类型均返回false,且要求类型必须完整定义。

std::is_scoped_enum 是什么,能判断什么
std::is_scoped_enum 是 C++23 引入的类型特征(type trait),用于在编译期判断一个类型是否为「作用域枚举」(scoped enum),也就是用 enum class 或 enum struct 定义的枚举。它对普通 enum(unscoped enum)返回 false,对 enum class E { a, b }; 这类返回 true。
注意:它只关心语法定义方式,不看是否显式指定了底层类型(比如 enum class E : int 仍是 scoped enum);也不管枚举值有没有重复、是否为空——只要语法是 enum class 或 enum struct,就满足条件。
怎么用:模板参数和静态成员 value
直接把类型作为模板参数传入,读取其 value 静态常量即可:
static_assert(std::is_scoped_enum_v<enum class e x>); // true static_assert(!std::is_scoped_enum_v<enum e x>); // false static_assert(!std::is_scoped_enum_v<int>); // false</int></enum></enum>
常见写法包括:
- 配合
static_assert做编译期约束 - 在
if constexpr中做分支选择 - 作为概念(concept)的一部分,例如
template<typename t> concept scoped_enum = std::is_scoped_enum_v<t>;</t></typename>
别忘了:C++23 才正式支持,GCC 12.1+、Clang 15+、MSVC 19.32+ 可用;若用旧标准,该模板不存在,会编译失败。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
容易误判的几种情况
几个看似像 scoped enum、实则不是的典型反例:
-
enum class E {};(空枚举)→std::is_scoped_enum_v<e></e>仍为true,合法 -
using E = enum class {x};→E是别名,但类型本身仍是 scoped enum,判断为true -
enum class E : char { x };→ 底层类型不影响判断,仍是true -
enum class E { x }; E e;→ 判断的是类型E,不是变量e;传错成decltype(e)没问题,但传e本体(非类型)会编译错误 -
template<typename t> void f() { static_assert(std::is_scoped_enum_v<t>); }</t></typename>→ 若调用f<int>()</int>,断言失败,报错信息里std::is_scoped_enum_v<int></int>明确为false
和 std::is_enum 的区别在哪
std::is_enum 更宽泛:它对 enum 和 enum class 都返回 true;而 std::is_scoped_enum 是它的子集判断——只有 scoped 才过。
所以实际中常组合使用:
template<typename t> constexpr bool is_unscoped_enum_v = std::is_enum_v<t> && !std::is_scoped_enum_v<t>;</t></t></typename>
这种写法能精准区分 unscoped vs scoped,避免把 enum class 当作传统枚举来隐式转换处理。尤其在序列化、反射或类型擦除场景下,这个区分很关键——scoped enum 默认不隐式转整数,行为更安全。
真正要用时,得确认编译器版本和标准模式(-std=c++23),否则连名字都找不到;另外别指望它能告诉你枚举有多少个值、有没有 operator==,它只回答“是不是 scoped enum”这一个问题。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










