在开关盒中使用按位或运算符

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