使用位掩码组合枚举值

Tho*_*lin 6 c c++ enums bitmask

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

我有一个简单的枚举:

enum State
{
    minimizing = 0,
    maximizing,

    minimized,
    maximized
};
Run Code Online (Sandbox Code Playgroud)

状态总是State.minimized或者State.maximized,并且可以在调整大小时具有其他状态.因此,可以最大限度地减少和最小化

Gau*_*ier 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;
Run Code Online (Sandbox Code Playgroud)

这样的话,你可以写信给田野currentnextundependently.

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

typedef struct {
    win_size_t current : 2;  // not tested
    win_size_t next : 2;
} state_t;
Run Code Online (Sandbox Code Playgroud)

先前给出的解决方案当然是有效的.我的观点是,如果你的变量myState有你的enum 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
Run Code Online (Sandbox Code Playgroud)

这允许您在一个任务中执行两项操作:

myState = MAXIMIZED | MINIMIZING;
Run Code Online (Sandbox Code Playgroud)

但也有你不想要的东西:

myState = MAXIMIZED | MINIMIZED;  // does that make sense?
Run Code Online (Sandbox Code Playgroud)


Vic*_*let 12

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

enum State 
{
  minimizing = 0x01, // 00000001
  maximizing = 0x02, // 00000010
  minimized  = 0x04, // 00000100
  maximized  = 0x08  // 00001000
}:
Run Code Online (Sandbox Code Playgroud)

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

  • @NatanYellin:确实如此,但是如果要再添加一个状态并使用十进制,则必须写入16.假设您要设置两位,即位4和位1.结果为18 in十进制,其可读性低于0x12(如果这不明显,请尝试识别在2398十进制中设置的位.如果您具有等效的0x95E,则更容易).如果您对设置了哪些位感兴趣,则可以使用十六进制. (4认同)
  • 味道问题,但我更喜欢:`(1u << 0)`,`(1u << 1)`,`(1u << 2)`,`(1u << 3)`.你的意思更清楚一点. (2认同)