enum class with scoping but without having to cast to underlying type

Viewed 95

I have this:

enum class Categories : uint32_t {
    C6 = 0x00000020,
    C7 = 0x00000040,
    C8 = 0x00000080,
    ...
};

I chose an enum class because it is great for scoping. But the downside is that when I need to use the categories as mask bits for bitwise operations I need to cast them to uint32_t first.

Example:

uint32_t masterCat = ((uint32_t)MyClass::Categories::C6) | ((uint32_t)MyClass::Categories::C7);

Is there a way I can get the same scoping benefit, without having to cast before using each time ? If I use a regular enum, then I lose the scoping benefit :(

Example:

uint32_t masterCat = (MyClass::Categories::C6) | (MyClass::Categories::C7);

2 Answers

Split the enum class into an enum and a class (or struct for convenience).

struct Categories {
    enum : uint32_t {
        C6 = 0x00000020,
        C7 = 0x00000040,
        C8 = 0x00000080,
    };
};

Since the enum is an embedded type, you need to specify Categories to access it, as in Categories::C6.

If this is inside another class, such as

class MyClass {
  public:
    struct Categories {
        enum : uint32_t {
            C6 = 0x00000020,
            C7 = 0x00000040,
            C8 = 0x00000080,
        };
    };
};

then you can use MyClass::Categories::C6 to refer to one of the enumerates, but neither MyClass::C6 nor C6 will work.

If you want to use bitwise and still forbid conversion to its underlying type, then you might add functions, so cast is done only once, on purpose:

enum class Categories : std::uint32_t {
    C6 = 0x00000020,
    C7 = 0x00000040,
    C8 = 0x00000080,
    //...
};

constexpr /*Categories*/ std::uint32_t operator | (Categories lhs, Categories rhs)
{
    return /*Categories*/(std::uint32_t(lhs) | std::uint32_t(rhs));
}
// operator& ...
Related