c++ - 在 C++ 中键入安全(r)位标志?

标签 c++ enums c++11 type-safety bitflags

在修改一些旧的 c++ 代码时,我遇到了几个 bitflags定义为枚举。

enum FooFlags
{
    FooFlag1 = 1 << 0,
    FooFlag2 = 1 << 1,
    FooFlag3 = 1 << 2
    // etc...
};

这并不少见,但让我感到困扰的是,一旦您开始组合标志,您就会丢失类型信息。

int flags = FooFlag1 | FooFlag2;   // We've lost the information that this is a set of flags relating to *Foo*

在 SO 上的一些搜索显示我不是 only one对此感到困扰。

另一种方法是将标志声明为 #defines 或 const 积分,因此按位运算不会转换类型(可能)。这样做的问题是它允许我们的位集通过整数或其他枚举与不相关的标志混合。

我熟悉 std::bitsetboost::dynamic_bitset ,但两者都不是为了解决我的问题。我正在寻找的是类似于 C# 的 FlagsAttribute .

我的问题是,对于(更多)类型安全的位标志集,还有哪些其他解决方案?

我将在下面发布我自己的解决方案。

最佳答案

您可以为返回正确类型化结果的枚举类型重载运算符。

inline FooFlags operator|(FooFlags a, FooFlags b) {
  return static_cast<FooFlags>(+a | +b);
}

需要注意的是,为了理论上安全,你应该手动声明可能的最大值,这样枚举类型的范围就可以保证捕获所有的组合。

  • 其实这并不需要:一个枚举的范围总是能够捕捉到所有的组合,因为一个枚举范围的最大正值总是(2^N)-1对于第一个N 能够表示最高的枚举数。该值的所有位均为 1。

关于c++ - 在 C++ 中键入安全(r)位标志?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4226960/

相关文章:

c++11 - unique_ptr<Derived> 到 unique_ptr<Base> 是否自动向上转换?

C++ 在更改与循环无关的内容后陷入无限循环

c++ - bool 值返回两次的问题(Arduino)

c++ - 数组和普通指针与 std::unique_ptr 的区别

swift - 从枚举中选择随机值

c++ - 用枚举填充 QMenu

c++11 - unique_ptr堆和栈分配

c++ - OpenGL 立方体的纹理不正确

c++ - std::map 发现在 C++ 中不起作用

c - VS 2010 中的枚举大小选项