如何在C ++中重用枚举运算符重载?

时间:2010-06-22 12:13:27

标签: c++ enums operator-overloading

我在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.对于枚举,但我讨厌为每一个枚举再次这样做。有没有一种很好的方法来重用运算符重载?

3 个答案:

答案 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)来提供操作,而不是编写自己的操作。