使用位掩码组合枚举值

时间:2011-02-07 11:32:13

标签: c++ c enums bitmask

我理解在枚举值中可以使用位掩码,但我不知道如何创建它。

我有一个简单的枚举:

enum State
{
    minimizing = 0,
    maximizing,

    minimized,
    maximized
};

状态始终为State.minimizedState.maximized,并且可以在调整大小时具有其他状态。因此,可以最大化并最小化

4 个答案:

答案 0 :(得分:18)

我将假设myState具有您enum State的类型。

enum的传统用法是创建此类变量可以采用的常量值。您希望将变量myState设置为enum中定义的值的组合

enum将1,2,4和8定义为有效值,但您希望能够将变量设置为4 | 2 = 6.虽然C对所有int使用实现定义的enum类型,但在C ++中并非如此。 myState = 6在C ++中无效。实际上,myState = 4在C ++中无效,您需要显式转换或使用enum的常量名称之一。

尽管在C中可行,但将myState设置为未由其类型定义的值(例如,为6)并不是一个好习惯。

在您的情况下,似乎结果的解决方案是:

typedef enum {
    OTHER,
    MINIMIZED,
    MAXIMIZED
} win_size_t;

typedef struct {
    win_size_t current;
    win_size_t next;
} state_t;

state_t myState;

这样,您可以独立写入currentnext字段。

如果您仍想拥有位字段,可以按位设置结构元素的大小。但它有点危险,位字段的实现取决于你的编译器。我甚至不确定编译器是否会接受在一个位字段中使用枚举类型(在C中应该没问题,因为enumint)。

typedef struct {
    win_size_t current : 2;  // not tested
    win_size_t next : 2;
} state_t;

以前给出的解决方案当然有效。我的观点是,如果您的变量myStateenum State作为类型,则应仅使用enum的成员作为其值,而不是组合。

也许myState有另一种类型,我知道什么。


如果myState不属于enum State类型,那么您可以组合使用enum中定义的常量。

enum State {
    MINIMIZING = (1u << 0),
    MAXIMIZING = (1u << 1),
    MINIMIZED  = (1u << 2),
    MAXIMIZED  = (1u << 3),
};

unsigned int myState = 0;

myState |= MAXIMIZED;  // sets that bit
myState &= ~MAXIMIZED; // resets that bit

这允许您在一个作业中做两件事:

myState = MAXIMIZED | MINIMIZING;

但也有你不想要的东西:

myState = MAXIMIZED | MINIMIZED;  // does that make sense?

答案 1 :(得分:12)

为枚举中的每个值使用不同的位,例如:

enum State 
{
  minimizing = 0x01, // 00000001
  maximizing = 0x02, // 00000010
  minimized  = 0x04, // 00000100
  maximized  = 0x08  // 00001000
}:

然后,您可以使用按位或(minimizing | maximized)组合多个值,并使用按位和(bool is_minimized = (flags & minimized);)测试值。

答案 2 :(得分:3)

我刚刚在VS2012中试过这个,如果您使用的是位域,优化器似乎可以正确组合位而无需任何帮助。

struct BITS { int x: 1; int y:1; };

然后

BITS b;
b.x = b.y = 1;

用一条指令设置两个位。

答案 3 :(得分:2)

您可以通过指定枚举中的所有字段并增加2的幂来获得此效果,以获得位掩码效果。例如,在您的情况下:

enum State
{
    minimizing = 1,
    maximizing = 2,

    minimized = 4,
    maximized = 8
};

因此,您可以使用(State.maximized | State.minimizing)的组合。但是,这不会仅限于State.maximizedState.minimized。如果你想这样做,你可以将它们转换成一个位,但我想在这个例子中你可能希望能够有一个既没有最大化也没有最小化的情况。