c ++使用按位或“|”在一个函数参数中的多个枚举

时间:2009-12-09 13:53:46

标签: c++ enums switch-statement binary-operators

我最近遇到过一些函数,你可以传递这样的多个枚举:

myFunction(One | Two);

因为我认为这是一种非常优雅的方式,所以我试图自己实现这样的东西:

void myFunction(int _a){
    switch(_a){
        case One:
            cout<<"!!!!"<<endl;
            break;
        case Two:
            cout<<"?????"<<endl;
            break;
    }
}

现在,如果我尝试用One |调用该函数二,我希望两个开关案例都被调用。我对二元运算符不是很好,所以我真的不知道该怎么做。任何想法都会很棒!

谢谢!

5 个答案:

答案 0 :(得分:14)

为此你必须制作如下的枚举:

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

即。枚举元素值应该是2的幂,以选择有效的case或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);
}

答案 1 :(得分:9)

按位运算符仅在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)

所以不是给出两个选项,而是给出了六个选项。

答案 2 :(得分:3)

通常以这种方式组合的参数是标志(具有单个位设置的值),其小数值为1,2,4,8等。假设One和Two遵循此规则,则不能使用开关检查两者。开关只遵循一条路径。你的组合参数不等于一个或两个,而是它们的组合(1 | 2 == 3)。您可以检查是否设置了一个或两个:

if (_a & One)
{

}
if (_a & Two)
{

}

请记住,没有显式值的标准枚举将向上计数,而不是使用下一位。如果你的下一个定义值是3,它可能等于3,这不是单个位的值,然后就好像你已经将两个标志(一个|两个)传递给该函数。您需要自己设置枚举值。

答案 3 :(得分:2)

你必须拆分可能的“令牌”(当然不重叠......使用2的力量):

if (_a & One) { ... }

不优雅的确使用1 switch语句做你想要的事情:使用if语句进行拆分。

答案 4 :(得分:2)

你最好用一组if语句来做...

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

编辑:您也可以在switch语句中执行此操作,但这将是一场噩梦。你需要这样的东西

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

case TWO:
   // Handle TWO.
   break;

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

它相对理智,只有2个选项,但一旦你得到更多它开始气球失控。如果您有32个选项,那么您将拥有一个不太适合任何计算机的switch语句。 “if”解决方案中的所有内容都更清晰,更清晰:)