C++ 使用位掩码组合枚举值
我知道可以在枚举值中使用位掩码,但我不知道如何创建它 我有一个简单的枚举:C++ 使用位掩码组合枚举值,c++,c,enums,bitmask,C++,C,Enums,Bitmask,我知道可以在枚举值中使用位掩码,但我不知道如何创建它 我有一个简单的枚举: enum State { minimizing = 0, maximizing, minimized, maximized }; 状态始终为状态。最小化或状态。最大化,并且可以在调整大小时具有附加状态。因此,可以将某些内容最大化和最小化您可以通过指定枚举中的所有字段并增加二次幂来获得位掩码效果,从而获得此效果。例如,在您的情况下: enum State { minimizing
enum State
{
minimizing = 0,
maximizing,
minimized,
maximized
};
状态始终为
状态。最小化
或状态。最大化
,并且可以在调整大小时具有附加状态。因此,可以将某些内容最大化和最小化您可以通过指定枚举中的所有字段并增加二次幂来获得位掩码效果,从而获得此效果。例如,在您的情况下:
enum State
{
minimizing = 1,
maximizing = 2,
minimized = 4,
maximized = 8
};
因此,您可以使用
(State.maximized | State.minimized)
的组合。但是,这不会应用仅为State.maximized
或State.minimized
的限制。如果您想这样做,您可以将它们转换为单个位,但我认为在本例中,您希望能够实现既不最大化也不最小化的情况。对枚举中的每个值使用不同的位,例如:
enum State
{
minimizing = 0x01, // 00000001
maximizing = 0x02, // 00000010
minimized = 0x04, // 00000100
maximized = 0x08 // 00001000
}:
然后,您可以使用按位or组合多个值(
最小化|最大化
),并使用按位and测试值(布尔最小化=(标志和最小化);
)。我将假设myState
具有您的枚举状态类型
enum
的传统用法是创建此类型变量可以采用的常量值。您希望将变量myState
设置为enum
中定义的值的组合
enum
将1、2、4和8定义为有效值,但您希望能够将变量设置为4 | 2=6。C使用您的实现定义<代码> int >代码>类型,对于所有的<代码> EnUM<代码>,C++中的情况不是这样。代码> MyStase= 6 在C++中无效。实际上,<代码> MyStase= 4 在C++中不是有效的,需要显式地使用或使用“代码> EnUM < /C> >的常量名称。< /P>
虽然在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;
这样,您就可以独立地写入字段current
和next
如果仍然希望有位字段,可以设置结构元素的大小(以位为单位)。但是这有点危险,位字段的实现取决于编译器。我甚至不确定编译器是否会接受在位字段中使用枚举类型(在C中应该可以,因为enum
s是int
)
当然,前面给出的解决方案是有效的。我的观点是,如果变量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
还有另一种类型,我知道些什么
如果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 | MINIMIZED; // does that make sense?
我刚刚在VS2012中尝试过,如果使用位字段,优化器似乎可以正确组合位,而无需任何帮助
struct BITS { int x: 1; int y:1; };
然后
用一条指令设置两个位。这条指令通常是用shifts编写的,但是,我如何使用它呢?像我这样:myState=minimized;如果(isMaximizing){myState=maximizing}
我想设置最大化状态,而不丢失最小化状态,那么您可以使用myState |=maximizing代码>。这设置了您感兴趣的位,而不涉及其他位。对于调零,使用myState&=~最大化代码>。进行比较时要小心,myState==minimized
不起作用,您需要(myState&minimized)==minimized
(或!=0
)。如果我是你,我会考虑一个字段为“当前状态”的结构,另一个为“下一个状态”。注意,虽然<代码>枚举状态< /C> >定义了一些常量,但并不定义它们的组合。如果myState
最小化并最大化,则结果值为0x02 | 0x04
,即0x06
。不是由枚举定义的值。品味问题,但我更喜欢:(1u为什么用十六进制表示法定义值?最小化=1
有效too@NatanYellin:是的,但是如果您要添加一个以上的状态并且使用十进制,则必须写入16。假设您要设置两位,第4位和第1位。结果是十进制的18,比0x12可读性差(如果这不明显,请尝试确定2398十进制中设置了哪些位。如果使用等效的0x95E,则更容易)。如果您对设置哪些位感兴趣,十六进制是最好的选择。谢谢!我选择了选项#1。事实上,最大化|最小化
是可能的,并且有两个枚举对可读性更好。请注意,将枚举限制为位文件是未定义的行为,结果取决于编译器。如果我错了,也请纠正我。@DavidTóth你似乎是对的,谢谢!
struct BITS { int x: 1; int y:1; };
BITS b;
b.x = b.y = 1;