说我有这样一堂课:
enum class Flags : char
{
FLAG_1 = 1;
FLAG_2 = 2;
FLAG_3 = 4;
FLAG_4 = 8;
};
Run Code Online (Sandbox Code Playgroud)
现在,我可以拥有一个具有类型标志的变量并为其分配值7吗?我可以这样做:
Flags f = Flags::FLAG_1 | Flags::FLAG_2 | Flags::FLAG_3;
Run Code Online (Sandbox Code Playgroud)
要么
Flags f = 7;
Run Code Online (Sandbox Code Playgroud)
出现这个问题是因为在枚举中我没有定义价值7.
T.C*_*.C. 12
你需要编写自己的重载operator|(并且可能是operator&等等).
Flags operator|(Flags lhs, Flags rhs)
{
return static_cast<Flags>(static_cast<char>(lhs) | static_cast<char>(rhs));
}
Run Code Online (Sandbox Code Playgroud)
只要该值在枚举值的范围内(否则为UB; [expr.static.cast]/p10),就可以很好地定义整数到枚举类型(范围与否)的转换.对于具有固定基础类型的枚举(包括所有作用域枚举; [dcl.enum]/p5),枚举值的范围与基础类型的值范围([dcl.enum]/p8)相同.如果基础类型没有修复,规则会比较棘手 - 所以不要这样做:)
Nut*_*ker 10
最好使用std::underlying_type而不是硬编码char类型。
Flags operator|(Flags lhs, Flags rhs) {
return static_cast<Flags>(
static_cast<std::underlying_type<Flags>::type>(lhs) |
static_cast<std::underlying_type<Flags>::type>(rhs)
);
}
Run Code Online (Sandbox Code Playgroud)
现在,您可以更改枚举的基础类型,而无需在每个按位运算符重载中更新该类型。
它应该处理任何枚举类型。我不确定它没有任何副作用并且是完全有效的 C++ 代码。如果有问题请告诉我。
template<class T, std::enable_if_t<std::is_enum_v<T>, int> = 0>
constexpr T operator|(T lhs, T rhs)
{
return static_cast<T>(
static_cast<std::underlying_type<T>::type>(lhs) |
static_cast<std::underlying_type<T>::type>(rhs));
}
Run Code Online (Sandbox Code Playgroud)