C++ 使用位掩码组合枚举值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4920783/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 16:55:07  来源:igfitidea点击:

Combining Enum Value using Bitmask

c++cenumsbitmask

提问by Thomas Joulin

I understand it's possible to use bitmasks in enum values, but I don't know how to create it.

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

I have a simple enum :

我有一个简单的枚举:

enum State
{
    minimizing = 0,
    maximizing,

    minimized,
    maximized
};

A state is always State.minimizedor State.maximized, and can have additional state on resize. So something can be Maximized and minimizing

状态始终为State.minimizedState.maximized,并且可以在调整大小时具有其他状态。所以有些东西可以最大化和最小化

回答by Gauthier

I am going to assume that myStatehas the type of your enum State.

我将假设它myState具有您的enum State.

The traditional use of enumis to create the constant values that a variable of this type can take. You wish to set you variable myStateto a combinationof the values defined in the enum.

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

The enumdefines 1, 2, 4, and 8 as valid values, yet you want to be able to set the variable to 4 | 2 = 6. While C uses your implementation-defined inttype for all enum, it is not the case in C++. myState = 6is not valid in C++. Actually, myState = 4is not either valid in C++, you need to cast explicitly or use one of the constant names of the enum.

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

Although possible in C, it is not good practice to set myStateto a value that is not defined by its type (for example to 6).

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

In your case, a solution that seems consequent would be:

在你的情况下,一个似乎随之而来的解决方案是:

typedef enum {
    OTHER,
    MINIMIZED,
    MAXIMIZED
} win_size_t;

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

state_t myState;

That way, you can write to the fields currentand nextundependently.

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

If you still want to have bit fields, you can set the size of the elements of your struct in bits. It is kind of dangerous though, the implementation of bit fields depend on your compiler. I am not even sure if compilers would accept to have an enum type in a bit field (should be ok in C, since enums are int).

如果您仍然想要位域,您可以以位为单位设置结构元素的大小。不过这有点危险,位域的实现取决于您的编译器。我什至不确定编译器是否会接受在位字段中使用枚举类型(在 C 中应该没问题,因为enums 是int)。

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

The previous given solutions are valid of course. My point is that if your variable myStatehas your enum Stateas type, it should only use the members of the enumfor its values, not a combination.

前面给出的解决方案当然是有效的。我的观点是,如果你的变量myState有你的enum Stateas 类型,它应该只使用 the 的成员enum作为它的值,而不是组合。

Maybe myStatehas another type, what do I know.

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



If myStateis not of the enum Statetype, then you may use the constants defined in your enumin combination.

如果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

This allows you to do two things in one assignment:

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

myState = MAXIMIZED | MINIMIZING;

But also things you are not likely to want:

但还有你不太可能想要的东西:

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

回答by Victor Nicollet

Use a different bit for every value in your enumeration, such as:

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

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

Then, you can combine multiple values with bitwise or (minimizing | maximized) and test for values with bitwise and (bool is_minimized = (flags & minimized);).

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

回答by Rico Mariani

I just tried this in VS2012, the optimizer seems to correctly combine bits without any need for assistance if you're using bitfields.

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

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

then

然后

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

Sets both bits with one instruction.

用一条指令设置两个位。

回答by dlanod

You can get this effect by specifying all fields in the enum and increased in powers of two to get the bitmask effect. For example, in your case:

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

enum State
{
    minimizing = 1,
    maximizing = 2,

    minimized = 4,
    maximized = 8
};

So you can then have your combinations of (State.maximized | State.minimizing). However this won't apply the restriction of only being State.maximizedor State.minimized. If you want to do that you could convert them to a single bit, but I imagine in this example you would want to be able to have a case where it is neither maximized nor minimized.

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