【问题标题】:enum class with scoping but without having to cast to underlying type具有范围但不必强制转换为基础类型的枚举类
【发布时间】:2022-01-07 17:57:57
【问题描述】:

我有这个:

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

我选择了一个枚举类,因为它非常适合范围界定。但缺点是,当我需要将类别用作按位运算的掩码位时,我需要先将它们转换为 uint32_t。

例子:

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

有没有一种方法可以获得相同的作用域优势,而不必在每次使用之前进行转换?如果我使用常规枚举,那么我会失去作用域优势:(

例子:

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

【问题讨论】:

标签: c++ c++11


【解决方案1】:

enum class 拆分为enumclass(或struct 为方便起见)。

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

由于enum 是嵌入式类型,您需要指定Categories 才能访问它,如Categories::C6

如果这是在另一个类中,例如

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

那么您可以使用MyClass::Categories::C6 来引用其中一个枚举,但MyClass::C6C6 都不起作用。

【讨论】:

  • 你能省略Enum,而只在struct Categories里面加上enum : uint32_t吗?
  • @Eugene 似乎也能正常工作
  • @Eugene 哦,对了,谢谢。我的意思是在将代码复制到答案之前检查一下。 (我不记得在指定基础类型时是否需要标识符,所以我认为第一个测试应该使用它。然后我忘了回到它。)
【解决方案2】:

如果您想按位使用,但仍然禁止转换为其基础类型,那么您可以添加函数,因此强制转换只进行一次:

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

【讨论】:

    猜你喜欢
    • 2019-08-29
    • 1970-01-01
    • 2013-01-13
    • 1970-01-01
    • 2019-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多