具有多种条件的开关盒

时间:2016-03-17 08:05:53

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

我有一个问题: 我有几个案例,我考虑用switch / case实现。

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

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;
}

3 个答案:

答案 0 :(得分:4)

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

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

#define FLAG 0x80000000

unsigned int value = X | (flag ? FLAG : 0);

switch (value)
{
case 1:
    break;
case 1 | FLAG:
    break;
}

答案 1 :(得分:2)

简短的回答是不!

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

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

答案 2 :(得分: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:
...
}

当然,这可以从更好的名字中受益。