【问题标题】:Using switch case for bitwise enums对按位枚举使用 switch case
【发布时间】:2018-02-23 18:40:22
【问题描述】:

我在这篇文章之后实现了我自己的类型安全位枚举运算符: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;
}

请注意,case 语句之间不应有 break;,因为可能有多个 case 为真。

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

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

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

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

【问题讨论】:

  • switch 不是解决此问题的合适工具。它不会测试某个值的特定位。使用if 语句。
  • 您做错了什么是发布了不符合 minimal reproducible example 要求的孤立代码块,如 stackoverflow.com 的 help center 中所述。
  • switch 将失败,因为 OutputStream::Console | OutputStream::File 既不完全是 OutputStream::Console,也不完全是 OutputStream::File。要选择 case,它必须等于 switch 语句。在任何情况下,case 失败都是连续的。随后的case 标签不会重新检查以查看某些条件是否为真。它只是贯穿case 标签,就好像它们不存在一样。我不确定您认为switch 是如何工作的,但很明显存在严重误解。
  • @NathanOliver 这就是我的想法。但是不,编译器会抱怨,因为在使用 C++ 11s 枚举类时没有隐式转换为 unsigned int,就像 C 的枚举所假设的那样
  • @AdrianKoch 考虑使用常规连续的enum 并改用std::bitset

标签: c++ c++11 enums bitwise-operators


【解决方案1】:

正如cmets中的其他人所说,switch不是最好的方法,但仍然可以这样做:

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 更好。至少您可以更好地控制位的评估顺序。

【讨论】:

    猜你喜欢
    • 2012-04-30
    • 2014-05-14
    • 1970-01-01
    • 1970-01-01
    • 2021-12-17
    • 2021-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多