我最近遇到过一些函数,你可以传递这样的多个枚举:
myFunction(One | Two);
因为我认为这是一种非常优雅的方式,所以我试图自己实现这样的东西:
void myFunction(int _a){
switch(_a){
case One:
cout<<"!!!!"<<endl;
break;
case Two:
cout<<"?????"<<endl;
break;
}
}
现在,如果我尝试用One |调用该函数二,我希望两个开关案例都被调用。我对二元运算符不是很好,所以我真的不知道该怎么做。任何想法都会很棒!
谢谢!
答案 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”解决方案中的所有内容都更清晰,更清晰:)