在开关盒中使用按位或运算符
Using bitwise or operator in switch case
我有枚举,
enum ENUM_MSG_TEXT_CHANGE {COLOR=0,SIZE,UNDERLINE};
void Func(int nChange)
{
bool bColor=false, bSize=false;
switch(nChange)
{
case COLOR:bColor=true;break;
case SIZE:bSize=true;break;
case COLOR|SIZE:bSize=true; bColor=true;break;
}
}
case SIZE: 和 case COLOR|SIZE: 都给出值 1,所以我收到错误 C2196:case 值“1”已被使用。如何在switch case中区分这两种情况?
谢谢
如果你想做一个位掩码,你的枚举的每个元素都必须对应一个 2 的幂数,所以它正好设置了 1 位。如果您以其他方式对它们进行编号,它将不起作用。所以,第一个元素应该是 1,然后是 2,然后是 4,然后是 8,然后是 16,依此类推,所以在对它们进行 orring 时不会重叠。此外,您应该单独测试每一位,而不是使用开关:
if (nChange & COLOR) {
bColor = true;
}
if (nChange & SIZE) {
bSize = true;
}
这两个标签
case SIZE:bSize=true;break;
case COLOR|SIZE:bSize=true; bColor=true;break;
计算结果为 1,因为 SIZE 被定义为具有值 1,并且标签 COLOR|SIZE
中使用的 bit-wise 运算符 |
也产生 1。
通常这样的枚举被声明为像
这样的位掩码类型
enum ENUM_MSG_TEXT_CHANGE { COLOR = 1 << 0, SIZE = 1 << 1, UNDERLINE = 1 << 2 };
在这种情况下这个标签
case COLOR|SIZE:bSize=true; bColor=true;break;
将等于 3。
当使用二进制 OR
(operator|
) 时,您需要为单个位(或位组合)赋值。由于 COLOR
的值为 0
,因此无法像您尝试的那样从位域中提取它。
此外,对于您拥有的三个 enum
,有 8 种可能的组合。要使用 switch
,您需要 8 个 case
标签。
考虑将此作为替代方案:
#include <iostream>
enum ENUM_MSG_TEXT_CHANGE : unsigned {
COLOR = 1U << 0U, // 0b001
SIZE = 1U << 1U, // 0b010
UNDERLINE = 1U << 2U // 0b100
};
void Func(unsigned nChange) {
// extract the set bits
bool bColor = nChange & COLOR;
bool bSize = nChange & SIZE;
bool bUnderline = nChange & UNDERLINE;
// print out what was extracted
std::cout << bUnderline << bSize << bColor << '\n';
}
int main() {
// test all combinations
for(unsigned change = 0; change <= (COLOR | SIZE | UNDERLINE); ++change) {
Func(change);
}
}
输出:
000
001
010
011
100
101
110
111
我有枚举,
enum ENUM_MSG_TEXT_CHANGE {COLOR=0,SIZE,UNDERLINE};
void Func(int nChange)
{
bool bColor=false, bSize=false;
switch(nChange)
{
case COLOR:bColor=true;break;
case SIZE:bSize=true;break;
case COLOR|SIZE:bSize=true; bColor=true;break;
}
}
case SIZE: 和 case COLOR|SIZE: 都给出值 1,所以我收到错误 C2196:case 值“1”已被使用。如何在switch case中区分这两种情况?
谢谢
如果你想做一个位掩码,你的枚举的每个元素都必须对应一个 2 的幂数,所以它正好设置了 1 位。如果您以其他方式对它们进行编号,它将不起作用。所以,第一个元素应该是 1,然后是 2,然后是 4,然后是 8,然后是 16,依此类推,所以在对它们进行 orring 时不会重叠。此外,您应该单独测试每一位,而不是使用开关:
if (nChange & COLOR) {
bColor = true;
}
if (nChange & SIZE) {
bSize = true;
}
这两个标签
case SIZE:bSize=true;break;
case COLOR|SIZE:bSize=true; bColor=true;break;
计算结果为 1,因为 SIZE 被定义为具有值 1,并且标签 COLOR|SIZE
中使用的 bit-wise 运算符 |
也产生 1。
通常这样的枚举被声明为像
这样的位掩码类型enum ENUM_MSG_TEXT_CHANGE { COLOR = 1 << 0, SIZE = 1 << 1, UNDERLINE = 1 << 2 };
在这种情况下这个标签
case COLOR|SIZE:bSize=true; bColor=true;break;
将等于 3。
当使用二进制 OR
(operator|
) 时,您需要为单个位(或位组合)赋值。由于 COLOR
的值为 0
,因此无法像您尝试的那样从位域中提取它。
此外,对于您拥有的三个 enum
,有 8 种可能的组合。要使用 switch
,您需要 8 个 case
标签。
考虑将此作为替代方案:
#include <iostream>
enum ENUM_MSG_TEXT_CHANGE : unsigned {
COLOR = 1U << 0U, // 0b001
SIZE = 1U << 1U, // 0b010
UNDERLINE = 1U << 2U // 0b100
};
void Func(unsigned nChange) {
// extract the set bits
bool bColor = nChange & COLOR;
bool bSize = nChange & SIZE;
bool bUnderline = nChange & UNDERLINE;
// print out what was extracted
std::cout << bUnderline << bSize << bColor << '\n';
}
int main() {
// test all combinations
for(unsigned change = 0; change <= (COLOR | SIZE | UNDERLINE); ++change) {
Func(change);
}
}
输出:
000
001
010
011
100
101
110
111