【问题标题】:Switch-case with several conditions [duplicate]具有多种条件的开关盒[重复]
【发布时间】:2016-07-03 10:59:06
【问题描述】:

我有一个问题: 我有几个案例,我想用开关/案例来实现。

我的代码看起来有点像这样:

switch( X)
{
  case 1:
    flag = true ;
        if ( flag ==true)
        {...}
        if ( flag ==false)
        {...}
    break ;

  case 2 :
    flag = true ;
        if ( flag ==true)
        {...}
        if ( flag ==false)
        {...}
    break ;

  case 3 :
    flag = true ;
        if ( flag ==true)
        {...}
        if ( flag ==false)
        {...}
    break ;
}

我可以像这样在开关中设置几个条件吗?

switch( X & flag)
{
  case ( 1 && flag ==true):
    {...}
    break;

  case ( 1 && flag ==false):
    {...}
    break;

  case ( 2 && flag ==true):
    {...}
    break;

  case ( 2 && flag ==false):
    {...}
    break;

  case ( 3 && flag ==true):
    {...}
    break;

  case (3 && flag ==false):
    {...}
    break;
}

【问题讨论】:

  • 不,你不能这样做,这不是语言的工作方式或设计方式。根据switch 的大小,您可以使用if 语句来检查标志,并根据结果使用两个switch 语句,至少应该使案例更简单。
  • flag 在您的第一个代码中始终为 true,因此没有理由使用 if 语句。
  • X的范围是多少?
  • 不,但考虑到flag 变量在所有情况下都必须具有相同的值,我会将整个switch 语句放在首先检查标志变量的if 块中。更好的是,将 switch 语句也放在另一个函数中,这样代码会更清晰。
  • 最好使用布尔表达式,如if (flag)if (!flag),而不是if (flag == true)if (flag == false)

标签: c++ switch-statement conditional-statements


【解决方案1】:

您可以使用关联容器来存储(键、函数)对而不是 switch 语句。它会慢一点,但你可以使用任意键。

void f(int X, bool flag)
{
    auto case1 = []() { ... };
    auto case2 = []() { ... };
    auto case3 = []() { ... };

    static const std::unordered_map< std::pair<int, bool>, std::function<void()>> select{
        { {0, true}, case1 },
        { {0, false}, case2 },
        { {42, true}, case3 },
        ...
    };

    auto const c = select.find( std::make_pair(x,flag) );
    if (c != select.end())
    {
        c->second();
    }
    else
    {
        // default case
    }
}

另一种选择是使用枚举命名案例(x,flag),并定义映射它们的函数。

enum class Cases {
    case1True,
    case2True,
    case1False,
    ...
}
Cases whichCase(int x, bool flag) {
    return case based on x and flag
}

switch (whichCase(x,flag))
{
case Cases::case1True:
case Cases::case1False:
...
}

当然这会受益于更好的名字。

【讨论】:

    【解决方案2】:

    简短的回答是否定的!

    但由于有时您想使用不同类型的条件语句,如果您希望代码看起来更好,最好重写代码:

    if(flag)
    { 
      switch (X)
      {
        ...
      }
    }
    else
    {
      switch (X)
      {
        ...
      }
    }
    

    【讨论】:

    • IMO 如果你添加一个案例更容易出错(更容易忘记其他)。
    【解决方案3】:

    我们不知道 X 的范围或变量类型,所以这个答案可能会也可能不会满足您的需求。

    假设 X 是 unsigned int 并且 X 的范围不需要 MSB,您可以在将值传递给 switch-statement 之前将标志放在 MSB 中:

    #define FLAG 0x80000000
    
    unsigned int value = X | (flag ? FLAG : 0);
    
    switch (value)
    {
    case 1:
        break;
    case 1 | FLAG:
        break;
    }
    

    【讨论】:

    • 比我快 ;) 我认为您应该指出 1 | FLAG 在这种情况下实际上意味着 value == 1 &amp;&amp; flag,对于不熟悉按位运算的人来说,我猜...
    • @Holt 也许为了可读性case 1 + FLAG: 会更好。或者 OP 可以使用枚举并为不同的值赋予有意义的名称。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-02
    相关资源
    最近更新 更多