【问题标题】:Compact non-repetitive way for an ALL flag in enums that represent bitflags in C++枚举中 ALL 标志的紧凑非重复方式,表示 C++ 中的位标志
【发布时间】:2019-05-03 11:48:52
【问题描述】:

我经常将枚举用于如下的位标志

enum EventType {
    NODE_ADDED = 1 << 0,
    NODE_DELETED = 1 << 1,
    LINK_ADDED = 1 << 2,
    LINK_DELETED = 1 << 3,
    IN_PIN_ADDED = 1 << 4,
    IN_PIN_DELETED = 1 << 5,
    IN_PIN_CHANGE = 1 << 6,
    OUT_PIN_ADDED = 1 << 7,
    OUT_PIN_DELETED = 1 << 8,
    OUT_PIN_CHANGE = 1 << 9,

    ALL = NODE_ADDED | NODE_DELETED | ...,
};

是否有一种简洁的重复方式来定义一个将所有其他标志组合在一个枚举中的 ALL 标志?对于小型枚举,上述方法效果很好,但假设一个枚举中有 30 个标志,这样做会很乏味。有什么工作(一般)像这样

ALL = -1

?

【问题讨论】:

  • 这不是告诉编译器枚举是 sizeof(enum) == 8 吗?如果编译器可以通过另一种方式优化到更少的空间,我不想对它工作。
  • ALL 是否只想要已定义值的位集,或者是否存在没有相关值的位集?
  • 最理想的情况是,我希望是这样,但是如果枚举的大小与手动方式(即自动扣除)完成的大小相同,那就足够了
  • 在上面显示的特定情况下,您可以使用ALL = (1 &lt;&lt; 10) - 1

标签: c++ enums flags enum-flags bitflags


【解决方案1】:

使用将始终涵盖所有其他选项的东西,例如:

ALL = 0xFFFFFFFF

或者正如 Swordfish 所说,您可以翻转无符号整数文字的位:

ALL = ~0u

要回答您的评论,您可以明确告诉编译器您希望枚举具有什么类型:

enum EventType : unsigned int

【讨论】:

  • 0xFFFFFFFF~0u~0ul~0ull。少写,少读,少出错。
  • @Swordfish 两者都是可能的,我更喜欢这个,因为它更清楚地表达了我的意图,但我想这是个人的。少读并不总是更好。
  • 但是有没有办法让编译器决定枚举应该具有的大小?
  • @PhilippMildenberger 该标准说“枚举的基础类型是一个整数类型,可以表示枚举中定义的所有枚举值。”是的。
  • @zett42 你指的是不相关的东西。 enum { foo = 42uul; }; 没有演员表。 dcl.enum/5.1 ff.
【解决方案2】:

这里的根本问题是您需要多少位。这取决于以前的枚举数。尝试在枚举中定义 ALL 会导致这种情况成为循环逻辑

相反,您必须在枚举之外定义它:

const auto ALL = (EventType) ~EventType{};

EventType{} 有足够的零,~ 将其转换为具有足够多的整数类型,因此您需要再次转换回EventType

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-24
    • 1970-01-01
    • 1970-01-01
    • 2018-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多