How to make enum class to work with the 'bit-or' feature?

前端 未结 1 1248
慢半拍i
慢半拍i 2021-01-02 08:06

I usually use enum with the \'bit-or\' or | together to allow an object has some options. How to make enum class to work with the \'bit-or\' featur

1条回答
  •  春和景丽
    2021-01-02 08:14

    You need to overload the operators for your enum class and implement them by casting to the underlying type:

    enum class foo : unsigned {
        bar = 1,
        baz = 2
    };
    
    foo operator |(foo a, foo b) {
        return static_cast(static_cast(a) | static_cast(b));
    }
    

    … of course this could be generalised (using SFINAE and std::underlying_type). That C++ doesn’t provide this out of the box is an oversight, in my opinion.

    Here’s how a general implementation might look like:

    // Intentionally undefined for non-enum types.
    template ::value>
    struct is_flag;
    
    template 
    struct is_flag : std::false_type { };
    
    template ::value>::type* = nullptr>
    T operator |(T lhs, T rhs) {
        using u_t = typename std::underlying_type::type;
        return static_cast(static_cast(lhs) | static_cast(rhs));
    }
    
    // … same for `&`, `~`. And maybe functions like `isset`, `set` and `unset`.
    

    This implementation ensures that the overload is only found for enums that are actually acting as flags. To mark an enum as a flag, you need to specialise is_flag:

    enum class a_flag : unsigned {
        foo = 0,
        bar = 1,
        baz = 2
    };
    
    template <> struct is_flag : std::true_type { };
    

    0 讨论(0)
提交回复
热议问题