如何将C++ 11枚举类用于标志

Nar*_*rek 7 c++ enums c++11

说我有这样一堂课:

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)相同.如果基础类型没有修复,规则会比较棘手 - 所以不要这样做:)

  • 您总是可以转换为[`std :: underlying_type <Flags> :: type`](http://en.cppreference.com/w/cpp/types/underlying_type),然后您不需要指定基础类型和它仍将始终在范围内. (3认同)

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)

现在,您可以更改枚举的基础类型,而无需在每个按位运算符重载中更新该类型。


Ole*_*ksa 5

它应该处理任何枚举类型。我不确定它没有任何副作用并且是完全有效的 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)