On 18 Nov 2025 13:46, Janko Dedic via Boost wrote:
I have always considered this a self-inflicted problem. Saying that an `enum class E { A=1, B=2, C=4 };` can have a value of `E{(int)E::A | (int)E::B}` is a category error. Of course, an object of type E _can_ have this representation, but `enum` is meant to express a full set of valid values. This helps readers understand code and compilers warn about unhandled enum values.
Exhaustive enums are just one use case, bitmasks are another. Enum is just an integer with a given set of predefined values, and using enums to form bitmasks is straightforward and has been done in the wild for ages. A utility that helps this use case would be useful, IMO.
Bit masks have been done effortlessly in C since forever. Just use a normal `enum E { A=1, B=2, C=4 };` and create flag sets with `unsigned flags = A | B;`.
Unscoped enums have known issues, like being implicitly convertible to ints, having no fixed underlying type by default and pouring enumerator names into the enclosing namespace. Enum classes address those issues.
If you really want a more modern solution that also makes sense in the type system, I have used a utility class template like this before.
``` enum class E { A, B, C }; flag_set<E> flags{E::A, E::B}; flags.add(E::C); flags.erase(E::A); bool b = flags.contains(E::B); ```
`flag_set<E>` can internally shift enum values and apply them to the underlying integer.
Why would you want that instead of the natural syntax with bitwise operators?