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
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 { };