我在C ++中有几个类似于旗帜的枚举。例如:
enum some_state {
state_normal = 1 << 0,
state_special = 1 << 1,
state_somethingelse = 1 << 2,
state_none = 0,
};
some_state var1;
现在使用像&
或|
这样的位运算符,我得到了编译器错误。我知道我可以重载operator |
et.al.对于枚举,但我讨厌为每一个枚举再次这样做。有没有一种很好的方法来重用运算符重载?
答案 0 :(得分:5)
enum some_state {
state_normal = 1 << 0,
state_special = 1 << 1,
state_somethingelse = 1 << 2,
state_none = 0,
};
int main() {
some_state var1 = state_normal;
some_state var2 = state_special;
unsigned int var3 = var1 | var2;
}
对我来说很好。你不能使用|,&amp;的原因没有重载的等等是因为编译器不能保证var1 |的结果var2是枚举中的有效值。如果要采用移位标志,则需要采用整数类型,而不是枚举类型。这在Direct3D等专业标题中一直使用。
答案 1 :(得分:3)
我试过并搜索过,我认为最好的解决方案是#define。基于something I found:
#define FLAGS(T) \
inline T operator |(const T s, const T e) { return (T)((unsigned)s | e); } \
inline T &operator |=(T &s, const T e) { return s = s | e; } \
inline T operator &(const T s, const T e) { return (T)((unsigned)s & e); } \
inline T &operator &=(T &s, const T e) { return s = s & e; } \
inline T operator ^(const T s, const T e) { return (T)((unsigned)s ^ e); } \
inline T &operator ^=(T &s, const T e) { return s = s ^ e; } \
inline T operator ~(const T s) { return (T)~(unsigned)s; }
这可以像:
一样使用enum some_state {
state_normal = 1 << 0,
state_special = 1 << 1,
state_somethingelse = 1 << 2,
state_none = 0,
};
FLAGS(some_state)
some_state var1;
对于Visual Studio,人们可能需要这样才能使一些警告静音:
#pragma warning(disable: 4505) // '*' : unreferenced local function has been removed
事实上,Windows SDK只有the DEFINE_ENUM_FLAG_OPERATORS
macro才能做到这一点。
另一种方法是包装类like DEF_ENUM_FLAGS_TYPE
uses。
或使用the LLVM_MARK_AS_BITMASK_ENUM
macro之类的内容。您可能需要最近的编译器。
答案 2 :(得分:2)
使用现有的模板库(例如bitwise-enum)来提供操作,而不是编写自己的操作。