C ++ multiple enumerations in a single function argument using bitwise or "|"

Recently, I came across some functions in which you can pass several enumerations as follows:

myFunction(One | Two); 

Since I think this is a really elegant way, I myself tried to implement something like this:

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

now if I try to call a function using One | Secondly, I want both switch boxes to be called. I am not very good with binary operators, so I do not know what to do. Any ideas would be great!

Thanks!

+6
c ++ enums binary-operators switch-statement
source share
5 answers

To do this, you need to make transfers like:

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

i.e. The value of an enumeration element must be 2 in order to select a valid register or if statement.

So when you like:

 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); } 
+11
source share

Bitwise operators behave well only with degrees 2:

  0010 | 0100 ------ 0110 // both bits are set 0110 & 0100 ------ 0100 // nonzero, ie true: the flag is set 

If you try to do the same with arbitrary numbers, you will get unexpected results:

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

Which contains possible (arbitrary) numbers in the form of set flags: 0001 (1), 0100 (4), 0101 (5), 1000 (8), 1001 (9), 1100 (12), 1101 (13)

So instead of giving two options, you just gave six.

+8
source share

Typically, arguments that are combined this way are flags (a value with one set of bits) with a decimal value of 1, 2, 4, 8, etc. Assuming one and two follow this rule, you cannot use the switch to test both. Switches follow only one path. Your combined argument is not equal to One or Two, but their combination (1 | 2 == 3). You can check if one or two is installed like this:

 if (_a & One) { } if (_a & Two) { } 

Remember that a standard enumeration without explicit values ​​will simply be counted up, rather than using the next bit. If your next setpoint value is Three, it will probably be 3, which is not the value of one bit, and then will act as if you passed both (One | Two) flags to a function. You will need to set the enumeration values ​​yourself.

+3
source share

You should separate the possible "tokens" (non-overlapping, of course ... use force 2):

 if (_a & One) { ... } 

It's not very elegant to do what you want with 1 switch: split statement with if .

+2
source share

You better do this with a set of if statements ...

ie

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

edit: You can also do this in the switch statement, but it will be a nightmare. You need something like this

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

Relatively reasonable for only two options, but as soon as you get more than that, it starts to get out of hand. If you have 32 options, you will have a switch statement that is hardly suitable for any machine. Everything in the "if" solution is much cleaner and much more reasonable :)

+2
source share

All Articles