如何解决在开关情况下使用按位或运算符
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 value'1'已经被使用。如何在切换案例中区分这两种情况?
谢谢
解决方法
如果要创建位掩码,枚举的每个元素都必须对应于2的幂的数字,因此它恰好设置了1位。如果您不给它们编号,它将无法正常工作。因此,第一个元素应该是1,然后是2,然后是4,然后是8,然后是16,依此类推,因此在排列它们时不会出现重叠。另外,您应该单独测试每一位,而不是使用开关:
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
也会产生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
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。