Let's say I have
enum class Flags : std::uint16_t
{
None = 0,
A = 0x0001,
B = 0x0002,
C = 0x0004
}
inline Flags operator|(Flags lhs, Flags rhs)
{
return static_cast<Flags>(static_cast<std::uint16_t>(lhs) | static_cast<std::uint16_t>(rhs));
}
inline Flags operator&(Flags lhs, Flags rhs)
{
return static_cast<Flags>(static_cast<std::uint16_t>(lhs) & static_cast<std::uint16_t>(rhs));
}
inline Flags operator|=(Flags& lhs, Flags rhs)
{
return lhs = lhs | rhs;
}
inline Flags operator&=(Flags& lhs, Flags rhs)
{
return lhs = lhs & rhs;
}
Is it possible to make the enum class contextually convertible to bool to allow someone to do
Flags f = /* ... */;
if (f & Flags::A) {
// Do A things
}
Although you can't accomplish this with strongly typed enums alone you can encapsulate the enum type and conversions in a class to get behavior similar to what you're looking for. It does take a bit more effort to put it together but not so much it will be cumbersome (unless you're doing dozens of enum base flags. In that case a template based solution might be desirable.
By encapsulating it in a class you gain all the necessary conversion operators necessary to perform the operations detailed in your question. These conversions go both ways and when coupled with operators at namespace scope provides (I hope) the behavior you are trying to achieve.
The code:
One downside I see to this is that it doesn't play well with enum related type traits (i.e.
std::underlying_type
).I don't think you can provide a conversion operator to
bool
, as there is no real instance of the class, but you can overload other operators. The natural one would beoperator!
:Then your program would do:
Which is really not natural but it would not be horribly surprising to others (as of what it means, they would probably be puzzled by the double negation).
Alternative, you can implement the operation as a named function to make it more readable:
Then again, if you really want implicit conversions, why are you using an enum class in the first place?