【问题标题】:Bitflag enums in C++C++ 中的位标志枚举
【发布时间】:2009-11-07 16:29:52
【问题描述】:

在 C++ 中使用枚举来存储位标志有点麻烦,因为一旦枚举值被 ORed,它们就会失去它们的枚举类型,这会在没有显式转换的情况下导致错误。

this question 的公认答案建议重载 | 运算符:

FlagsSet operator|(FlagsSet a, FlagsSet b) 
{ 
    return FlagsSet(int(a) | int(b)); 
}

我想知道这个方法是否有任何运行时影响?

【问题讨论】:

  • +1 因为我还不知道这种技术。
  • 将 int 切换到 unsigned - 否则您要求其他代码以符号扩展问题告终(位标志永远不会签名!那将是非常愚蠢的)。

标签: c++ enums type-systems bitflags


【解决方案1】:

在正确性方面的运行时影响?不 - 这应该正是您想要的。

运行时对速度的影响?我希望任何体面的编译器都能将其正确优化到发布版本的最少指令数(尽管您可能想添加 inline 以确保)。

【讨论】:

  • +1。关于inline:智能编译器会自行决定忽略关键字和内联代码;如今,出于性能原因,将函数标记为内联通常是没有用的。但是,添加 inline 的原因有很大不同,假设函数是在头文件中定义的。
【解决方案2】:

它可能会执行三个副本和一个函数调用,禁止 RVO、寄存器和/或内联优化。

裸按位或运算本身通常分解为单个处理器指令。

【讨论】:

  • 这可能不仅不是瓶颈,而且你承认自己编译器可能足够聪明,可以优化这些东西。
【解决方案3】:

代码是正确的。

代码将与没有类型转换的速度相同。

但是代码是否快速无关紧要,因为名为“FlagSet”的类型很可能会在条件测试的上下文中使用(->“if (Flag)”),这比对速度的影响更大寄存器大小的两个值的按位“或”。

【讨论】:

    【解决方案4】:

    将 std::bitset 用于您的位标志...更简单;) 或 boost::dynamic_bitset。

    【讨论】:

    • 这并没有完成位标志使用语义或减少一点开销!位集在道德上等同于 vector<bool>,它与一组位标志完全不同。
    • 很丢脸 :( - 抱歉,我自己的无知 - bitset 确实有按位运算,不是向量 - 我是个白痴。:(
    猜你喜欢
    • 2018-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-17
    • 1970-01-01
    • 1970-01-01
    • 2012-11-18
    • 1970-01-01
    相关资源
    最近更新 更多