在 C++ 中输入 safe(r) 位标志?
在修改一些旧的 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*
一种替代方法是将标志声明为 #defines 或 const 积分,因此按位运算不会(可能)转换类型。问题是它允许我们的位集通过整数或其他枚举与不相关的标志混合。
我熟悉 std::bitset 和 boost::dynamic_bitset,但这两者都不是为了解决我的问题而设计的。我正在寻找类似于 C# 的 FlagsAttribute 的东西。
我的问题是,对于(更多)类型安全的位标志集还有哪些其他解决方案?
我将在下面发布我自己的解决方案。
While revising some old c++ code, I ran across several bitflags defined as enums.
enum FooFlags
{
FooFlag1 = 1 << 0,
FooFlag2 = 1 << 1,
FooFlag3 = 1 << 2
// etc...
};
This isn't uncommon, but it bothered me that as soon as you start to combine flags, you lose the type information.
int flags = FooFlag1 | FooFlag2; // We've lost the information that this is a set of flags relating to *Foo*
Some searching on SO showed that I'm not the only one bothered by this.
One alternative is to declare flags as #defines or const integrals, so bitwise operations wouldn't transform the type (probably). The problem with this is it allows our bit set to commingle with unrelated flags, via ints or other enums.
I'm familiar with std::bitset and boost::dynamic_bitset, but neither are designed to address my issue. What I'm looking for is something like C#'s FlagsAttribute.
My question is, what other solutions are there for a (more) type safe set of bitflags?
I'll post my own solution below.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以重载返回正确类型化结果的枚举类型的运算符。
应该注意的是,为了理论上安全,您应该手动声明可能的最高值,以便保证枚举类型的范围捕获所有组合。(2^N)-1
,因为第一个N
能够表示最高的枚举数。该值的所有位均为 1。You can overload operators for enumeration types that return the proper typed result.
It should be noted that to be theoretically safe, you should declare manually the highest possible value so the enumeration type's range is guaranteed to catch all the combinations.(2^N)-1
for the firstN
being able to represent the highest enumerator. That value has all bits 1.这是我自己的解决方案,使用当前版本的 VS2010 允许的 c++0x 元素:
该界面是根据 std::bitset。我的目标是忠实于类型安全和最小(如果有)开销的 C++ 精神。我欢迎对我的实施提出任何反馈。
这是一个最小的例子:
Here's my own solution, using elements of c++0x that the current version of VS2010 allows for:
The interface is modeled after std::bitset. My aim was to be true to the c++ ethos of type safety and minimal (if any) overhead. I'd welcome any feedback on my implementation.
Here's a minimal example:
我想我可能会为
enum class
添加一个 c++11 版本,如果你的 c++11 版本支持它,我想这将是
constexpr
的主要候选者Thought I might add a c++11 version for
enum class
If you c++11 version supports it I guess this would be a prime candidate for
constexpr