Home > Blockchain >  enum class with scoping but without having to cast to underlying type
enum class with scoping but without having to cast to underlying type

Time:12-01

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);

CodePudding user response:

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.

CodePudding user response:

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