C++ несколько перечислений в одном аргументе функции, использующем поразрядно или “|”

Один элемент, чтобы быть очень осторожным с по этой теме <script> элемент. Если у Вас будет внешний исходный файл, он вызовет проблемы сам при закрытии его. Попробуйте его:

<!-- this will not consistently work in all browsers! -->
<script type="text/javascript" src="external.js" />

Это будет работать в Firefox, но перерывах в IE6, по крайней мере. Я знаю, потому что я столкнулся с этим, когда фанатично сам закрытие каждого элемента я видел;-)

9
задан moka 9 December 2009 в 13:53
поделиться

5 ответов

Для этого вам нужно создать перечисления вроде:

enum STATE {
  STATE_A = 1,
  STATE_B = 2,
  STATE_C = 4
};

т.е. значение элемента перечисления должно быть в степени 2, чтобы выбрать допустимый регистр или оператор if.

Итак, когда вам нравится:

void foo( int state) {

  if ( state & STATE_A ) {
    //  do something 
  }

  if ( state & STATE_B ) {
    //  do something 
  }

  if ( state & STATE_C ) {
    //  do something 
  }   
}

int main() {
  foo( STATE_A | STATE_B | STATE_C);
}
14
ответ дан 4 December 2019 в 07:23
поделиться

Побитовые операторы хорошо себя ведут только со степенью 2:

  0010
| 0100
------
  0110  // both bits are set


  0110
& 0100
------
  0100  // nonzero, i.e. true: the flag is set

Если вы попытаетесь сделать то же самое с произвольными числами, вы получите неожиданные результаты:

  0101  // 5
| 1100  // 12
------
  1101  // 13

Который содержит возможные (произвольные ) номера как установленные флаги: 0001 (1), 0100 (4), 0101 (5), 1000 (8), 1001 (9), 1100 (12), 1101 (13)

Итак, вместо двух вариантов вы просто дали шесть.

9
ответ дан 4 December 2019 в 07:23
поделиться

Вы должны разделить возможные «токены» (без перекрытия, конечно ... используйте степень 2):

if (_a & One) { ... }

Не элегантно, действительно делайте то, что вы хотите, с одним оператором switch: разделите с помощью if операторы.

2
ответ дан 4 December 2019 в 07:23
поделиться

Вам лучше сделать это с помощью набора операторов if ...

т.е.

if ( _a & ONE )
{
   // Do stuff.
}
if ( _a & TWO )
{
  // Do other stuff.
}

edit: Вы также можете сделать это с помощью оператора switch, но это будет кошмар. Вам понадобится что-то вроде этого

switch( _a )
{
case ONE:
   // Handle ONE.
   break;

case TWO:
   // Handle TWO.
   break;

case ONE | TWO:
   // Handle ONE.
   // Handle TWO.
   break;
};

Это относительно разумно только для двух вариантов, но как только вы получите больше, он начинает выходить из-под контроля. Если у вас есть 32 варианта, у вас будет оператор switch, который вряд ли поместится на любой машине. Все в "если" решение намного чище и разумнее :)

2
ответ дан 4 December 2019 в 07:23
поделиться

Обычно аргументы, объединенные таким образом, представляют собой флаги (значение с одним набором битов) с десятичным значением 1, 2, 4, 8 и т. Д. Предполагая, что за этим следуют один и два. Правило, вы не можете использовать переключатель для проверки обоих. Коммутаторы следуют только по одному пути. Ваш комбинированный аргумент равен не одному или двум, а их комбинации (1 | 2 == 3). Вы можете проверить, установлен ли One или Two следующим образом:

if (_a & One)
{

}
if (_a & Two)
{

}

Помните, что стандартное перечисление без явных значений будет просто считать вверх, а не использовать следующий бит. Если ваше следующее определенное значение - три, оно, скорее всего, будет равно 3, что не является значением одного бита, и будет действовать так, как если бы вы передали функции оба флага (One | Two). Вам нужно будет установить значения перечисления самостоятельно.

3
ответ дан 4 December 2019 в 07:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: