std::is_scoped_enum 是 C++23 引入的类型特性,用于编译期判断类型是否为 enum class 或 enum struct 定义的作用域枚举;仅匹配语法定义,对裸 enum 和非枚举类型均返回 false。
std::is_scoped_enum 是 C++23 引入的类型特性(type trait),用于在编译期判断一个类型是否为作用域枚举(scoped enum),也就是用 enum class 或 enum struct 定义的强类型枚举。它不关心枚举是否有底层类型、是否显式指定、是否为空,只认定义语法:只有 enum class 和 enum struct 才返回 true;所有 enum(无 class 修饰)都返回 false,哪怕底层类型相同、值域一致。
它是一个变量模板(C++14 起支持的 value 成员),直接取 ::value 即可:
static_assert(std::is_scoped_enum_v<enum class E {}>); // truestatic_assert(!std::is_scoped_enum_v<enum E {}>); // true(即 false)static_assert(!std::is_scoped_enum_v<int>); // true(即 false)
常见误用点:
std::is_scoped_enum_v<e> 是错的,必须是类型,如 std::is_scoped_enum_v<decltype(e)>
std::is_enum 混用——后者对两种枚举都返回 true,而 std::is_scoped_enum 是它的严格子集enum class 加了 using operator int = ...,它仍是 scoped有人试图用 std::is_convertible<E, int>::value 或 std::underlying_type_t<E> 来间接判断,这是不可靠的:
立即学习“C++免费学习笔记(深入)”;
enum class E : int {} 和 enum E : int {} 底层类型完全一样,但前者是 scoped,后者不是enum class E {} 默认不可转成 int,但 enum E {} 可以——但这不是判断依据,因为用户可能给 enum class 添加自定义转换运算符std::underlying_type 对两者都有效,无法区分唯一正解就是直接用 std::is_scoped_enum_v<T>,它不依赖行为,只依赖语言定义。
std::is_scoped_enum 是 C++23 特性,但在 GCC 12+、Clang 15+、MSVC 19.32+ 中已作为扩展提前支持(需开启 -std=c++20 或更高,并确认标准库版本)。若项目还停留在 C++20 之前,没有替代方案——宏或 SFINAE 都无法可靠检测 enum class 语法,因为它是语法层面的分类,不是类型属性。
典型使用场景包括:
enum class 提供 JSON 序列化(避免传统枚举污染命名空间)enum
注意:它只回答“是不是 enum class”,不回答“有没有重复值”“是否包含 operator==”这类问题——那些得靠其他机制验证。