Объединение значения Enum с использованием битовой маски - PullRequest
6 голосов
/ 07 февраля 2011

Я понимаю, что можно использовать битовые маски в значениях перечисления, но я не знаю, как его создать.

У меня есть простое перечисление:

enum State
{
    minimizing = 0,
    maximizing,

    minimized,
    maximized
};

Состояние всегдаState.minimized или State.maximized и может иметь дополнительное состояние при изменении размера.Так что что-то можно максимизировать и минимизировать

Ответы [ 4 ]

18 голосов
/ 07 февраля 2011

Я собираюсь предположить, что 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;

Таким образом, вы можете писать в поля current и next независимо.

Если вы все еще хотите иметь битовые поля, вы можете установить размер элементов вашей структуры в битах. Хотя это опасно, реализация битовых полей зависит от вашего компилятора. Я даже не уверен, что компиляторы согласятся иметь тип enum в битовом поле (должно быть нормально в C, поскольку enum s int).

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

Предыдущие приведенные решения действительны, конечно. Я хочу сказать, что если ваша переменная 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

Это позволяет вам делать две вещи в одном назначении:

myState = MAXIMIZED | MINIMIZING;

Но также вещи, которые вы вряд ли захотите:

myState = MAXIMIZED | MINIMIZED;  // does that make sense?
12 голосов
/ 07 февраля 2011

Используйте разные биты для каждого значения в вашем перечислении, например:

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

Затем вы можете объединить несколько значений с побитовой или (minimizing | maximized) и проверить значения с помощью побитовой и (bool is_minimized = (flags & minimized);).

3 голосов
/ 07 сентября 2012

Я только что попробовал это в VS2012, оптимизатор, кажется, правильно комбинирует биты без какой-либо помощи, если вы используете битовые поля.

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

затем

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

Устанавливает обабиты с одной инструкцией.

2 голосов
/ 07 февраля 2011

Вы можете получить этот эффект, указав все поля в перечислении и увеличившись в степени двух, чтобы получить эффект битовой маски. Например, в вашем случае:

enum State
{
    minimizing = 1,
    maximizing = 2,

    minimized = 4,
    maximized = 8
};

Таким образом, вы можете иметь свои комбинации (State.maximized | State.minimizing). Однако это не будет применять ограничение только State.maximized или State.minimized. Если вы хотите сделать это, вы можете преобразовать их в один бит, но я думаю, что в этом примере вы захотите иметь случай, когда он не максимизируется и не минимизируется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...