I have the below sample code. I was always under the impression that doing Bitwise OR on enum values, will allow me to check the result (using Bitwise AND) to see which enum values are included in the result and which are not.
For example, if I do result = mouse | headphone
, then I can check agaist result & mouse == mouse
as condition to know if mouse
is included in result
or not. But it seem that whatever I &
result with, say X, I always end up with X. Why?
In the below code, I thought that the if should fail since straw
was not included in options
, but it does not..
#include <iostream>
#include <iomanip>
using namespace std;
enum Stock
{
milk,
choclate,
tv,
cable,
mouse,
fan,
headphone,
cup,
straw,
pen,
candy,
glasses,
book,
plug
};
int main()
{
Stock options = static_cast<Stock>( static_cast<int>(mouse) | static_cast<int>(headphone)
| static_cast<int>(cup) | static_cast<int>(pen) );
if ((static_cast<int>(loptions)) & (static_cast<int>(straw)) == static_cast<int>(straw))
{
cout << "bring straw!" << endl;
}
system("PAUSE");
return 0;
}
Edit:
Even when I add unique-bit set for the enum values, it does not work. For the below code, it ignores both if() statements when I am expecting it to display "bring cup"
instead:
enum Stock
{
milk = 1,
choclate = 2,
tv = 4,
cable = 8,
mouse = 16,
fan = 32,
headphone = 64,
cup = 128,
straw = 256,
pen = 512,
candy = 1024,
glasses = 2048,
book = 4096,
plug = 8192
};
int main()
{
Stock options = static_cast<Stock>(static_cast<int>(mouse) | static_cast<int>(headphone)
| static_cast<int>(cup) | static_cast<int>(pen));
if ((static_cast<int>(options)) & (static_cast<int>(straw)) == static_cast<int>(straw))
{
cout << "bring straw!" << endl;
}
if ((static_cast<int>(options)) & (static_cast<int>(cup)) == static_cast<int>(cup))
{
cout << "bring cup!" << endl;
}
system("PAUSE");
return 0;
}
To use enums as bitsets (or flags) you need to make sure the binary representation for each enum value contains exactly one bit set to 1. In other words, each enum value needs to be a power of two. Example :
enum Stock
{
milk = 1, // 0b0001
choclate = 2, // 0b0010
tv = 4, // 0b0100
cable = 8 // 0b1000
// etc.
};
Otherwise, bit-wise logical operators won't be able to differentiate between certain values and certain combinations of other values. In the original code chocolate
, tv
and cable
have the values 1
, 2
and 3
respectively. In binary, that is 01
, 10
and 11
. ORing chocolate
and tv
produces 11
(0b01 | 0b10 == 0b11
) which is the same value as cable
. The combination of the chocolate
and tv
is not distinguishable from the cable
flag.
But c++ provides std::bitset
. This class allows you to easily manipulate a bit set in a way similar to an array of bits. You can then just use your original enum and use each enum value as the index of a bit.