我通常使用带有“按位或”或|
的enum
来允许一个对象拥有一些选项。如何使枚举类与“按位或”功能配合工作?
我通常使用带有“按位或”或|
的enum
来允许一个对象拥有一些选项。如何使枚举类与“按位或”功能配合工作?
enum class foo : unsigned {
bar = 1,
baz = 2
};
foo operator |(foo a, foo b) {
return static_cast<foo>(static_cast<unsigned>(a) | static_cast<unsigned>(b));
}
当然,这可以通过使用SFINAE和std :: underlying_type
进行泛化。在我看来,C ++没有提供这个功能是一个疏忽。
以下是通用实现的示例:
// Intentionally undefined for non-enum types.
template <typename T, bool = std::is_enum<T>::value>
struct is_flag;
template <typename T>
struct is_flag<T, true> : std::false_type { };
template <typename T, typename std::enable_if<is_flag<T>::value>::type* = nullptr>
T operator |(T lhs, T rhs) {
using u_t = typename std::underlying_type<T>::type;
return static_cast<T>(static_cast<u_t>(lhs) | static_cast<u_t>(rhs));
}
// … same for `&`, `~`. And maybe functions like `isset`, `set` and `unset`.
这个实现确保只有作为标志位的枚举才能找到重载。要将枚举标记为标志位,您需要特化 is_flag
:
enum class a_flag : unsigned {
foo = 0,
bar = 1,
baz = 2
};
template <> struct is_flag<a_flag> : std::true_type { };
enum class Foo { operator| = default; }
的语法。 - MSaltersoperator|
给出一个在范围内的值而做的所有工作,这个操作符竟然还缺失,真是令人惊讶。 - MSalters