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& ...