Michel de Ruiter Michel de Ruiter - 3 months ago 12
C++ Question

How to reuse enum operator overloads in C++?

I have several flag-like enumerations, in C++. For example:

enum some_state {
state_normal = 1 << 0,
state_special = 1 << 1,
state_somethingelse = 1 << 2,
state_none = 0,
};
some_state var1;


Now on using bit operators like
&
or
|
, I get compiler errors. I know I can overload
operator |
et.al. for enums, but I hate to do that again for each and every enum. Is there a nice way to reuse the operator overloads?

Answer

I tried and searched, and I think the best solution is a #define. Based on 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; }

This can be used like:

enum some_state {
  state_normal        = 1 << 0,
  state_special       = 1 << 1,
  state_somethingelse = 1 << 2,
  state_none          = 0,
};
FLAGS(some_state)

some_state var1;

For Visual Studio one might need this to silence some warnings:

#pragma warning(disable: 4505) // '*' : unreferenced local function has been removed

In fact, the Windows SDK has the DEFINE_ENUM_FLAG_OPERATORS macro to do just that.


A different approach is a wrapper class like DEF_ENUM_FLAGS_TYPE uses.

Or use something like the LLVM_MARK_AS_BITMASK_ENUM macro. You might need a recent compiler though.

Comments