对按位枚举使用 switch case

Using switch case for bitwise enums

我在这篇文章之后实现了自己的类型安全按位枚举运算符:http://blog.bitwigglers.org/using-enum-classes-as-type-safe-bitmasks/

这是我正在谈论的枚举:

enum class OutputStream : unsigned int
    {
        None = 0,
        // Using bitshift operator (always one bit set to 1)
        Console = 1 << 0,
        File = 1 << 1,
        Other = 1 << 2
    };

如果您想知道,它用于日志记录功能。

问题: 我想在 switch 语句中使用枚举,例如

switch(stream)
{
    case OutputStream::Console:
        //Do this
    case OutputStream::File:
        //Do that
    default:
        break;
}

请注意,案例陈述之间不应有 break;,因为不止一个案例可能为真。

但是,这似乎行不通。更准确地说,当我使用 OutputStream::Console | OutputStream::File 时,两种情况都不会执行。

我对这个问题的唯一解决方案是这个看起来很笨拙的 if 语句:

if((stream & OutputStream::Console) != OutputStream::None) { /*Do this*/ }
if((stream & OutputStream::File) != OutputStream::None) { /*Do that*/ }

但对我来说,这违背了需要基于枚举的解决方案的意义。我做错了什么?

正如评论中其他人所说,切换不是最好的方法,但仍然可以做到:

for (int bit = 1; bit <= (int) OutputStream::LAST; bit <<= 1)
{
    switch((OutputStream) (bit & stream))
    {
        case OutputStream::Console:
            //Do this
            break;
        case OutputStream::File:
            //Do that
            break;

        // etc...

        // no default case no case 0!
    }
}

所以基本上你会遍历所有单独的位,对于每个测试它是否存在于 stream 变量中并跳转到适当的 case,或者如果它是 0 则跳转到任何地方。

但在我看来,个别的ifs更好。至少您可以更好地控制位评估的顺序。