C++如何实现保留作用域优势且无需强转底层类型的枚举
实现方案
有两种常用的实现方式可以同时保留enum class的作用域特性,且无需每次手动强转即可做位运算:
方案1:为目标枚举单独重载位运算符
直接针对你的Categories枚举类重载需要的位运算操作符(支持|/&/^/~以及对应复合赋值运算符),仅需实现一次即可全局生效:
#include <cstdint> class MyClass { public: enum class Categories : uint32_t { C6 = 0x00000020, C7 = 0x00000040, C8 = 0x00000080, // 其余枚举值 }; }; // 重载按位或运算符,返回值可按需选uint32_t或者枚举类型 inline uint32_t operator|(MyClass::Categories lhs, MyClass::Categories rhs) { return static_cast<uint32_t>(lhs) | static_cast<uint32_t>(rhs); } // 其余位运算符可按相同逻辑重载
实现完成后即可直接使用你期望的调用写法:
uint32_t masterCat = MyClass::Categories::C6 | MyClass::Categories::C7;
方案2:通用模板支持多个枚举类
如果项目中存在多个需要做位运算的枚举类,可以实现通用模板,避免重复写重载逻辑:
#include <type_traits> #include <cstdint> // 启用位运算的标记模板,需要支持位运算的枚举单独特化该模板 template<typename T> constexpr bool enable_enum_bitwise = false; // 通用按位或重载 template<typename T> requires std::is_enum_v<T> && enable_enum_bitwise<T> uint32_t operator|(T lhs, T rhs) { return static_cast<std::underlying_type_t<T>>(lhs) | static_cast<std::underlying_type_t<T>>(rhs); } // 其余位运算符均可按该逻辑实现通用模板
如果你使用的是C++11/14标准,可以将上述通用模板中的
requires约束替换为std::enable_if实现相同的编译期校验效果。
需要给指定枚举启用位运算时,仅需加一行特化声明即可:
template<> constexpr bool enable_enum_bitwise<MyClass::Categories> = true;
补充说明
如果使用C++23及更高版本标准,还可以使用标准库提供的std::to_underlying工具简化强转写法,相比手动写C风格强转更安全,但仍需要每次调用,便捷性低于重载运算符方案:
uint32_t masterCat = std::to_underlying(MyClass::Categories::C6) | std::to_underlying(MyClass::Categories::C7);
内容的提问来源于stack exchange,提问作者Rahul Iyer
相关产品推荐
相关产品推荐

