Компактный неповторяющийся способ для флага ALL в перечислениях, которые представляют битовые флаги в C++

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

enum EventType {
    NODE_ADDED = 1 << 0,
    NODE_DELETED = 1 << 1,
    LINK_ADDED = 1 << 2,
    LINK_DELETED = 1 << 3,
    IN_PIN_ADDED = 1 << 4,
    IN_PIN_DELETED = 1 << 5,
    IN_PIN_CHANGE = 1 << 6,
    OUT_PIN_ADDED = 1 << 7,
    OUT_PIN_DELETED = 1 << 8,
    OUT_PIN_CHANGE = 1 << 9,

    ALL = NODE_ADDED | NODE_DELETED | ...,
};

Есть ли чистый, менее повторяющийся способ определения флага ALL, который объединяет все другие флаги в перечислении? Для небольших перечислений вышеупомянутое работает хорошо, но допустим, что в перечислении есть 30 флагов, это будет утомительно делать таким образом. Работает ли что-то (в общем) так

ALL = -1

?

2 ответа

Решение

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

ALL = 0xFFFFFFFF

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

ALL = ~0u

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

enum EventType : unsigned int

Основная проблема здесь в том, как вам могут понадобиться однобитные. Это зависит от количества счетчиков ранее. Попытка определить ALL внутри перечисления делает это случай круговой логики

Вместо этого вы должны определить его вне перечисления:

const auto ALL = (EventType) ~EventType{};

EventType{} имеет достаточно нулей, ~ превращает его в целочисленный тип с достаточным количеством, поэтому вам нужен еще один приведение EventType

Другие вопросы по тегам