通过使用数组函数摆脱switch case

时间:2013-11-20 18:53:48

标签: c++

我想摆脱以下示例中的切换案例:

for ( int i = 0; i < 7; ++i )
    {
            switch (i)
            {
            case 2: case 5: case 6:
                if (value < 0)
                {
                  reportError(param);
                  return;
                }
                break;
            case 3: case 4:
                if (value <= 0)
                {
                  reportError(param);
                  return;
                }
                break;
             default:
                ;
            }
    }

我想做这样的事情:

    |
                                                        |
                                                       '''   ---- (error)
                                                        '
std::binary_function<double, double, bool> checks[] = { 0, less_equal<double>(), 
                                                        less<double>(), less<double>(),
                                                        less_equal<double>(),
                                                        less_equal<double>(), 
                                                        0 } ; 

for(int i = 0; i < 7; ++i)
{
   if( bind2nd(checks[i], 0)(value) )    <----- error
   {
      reportError(param);
      return;
   }
}

如何摆脱开关案例(在C ++ 98中并且不使用boost)?

2 个答案:

答案 0 :(得分:1)

您无需绑定任何内容。

if (checks[i](value, 0))

您也不需要一系列仿函数对象。函数指针适用于您显示的逻辑。

bool (*(checks[]))(double, double) = { /* ... */ };

答案 1 :(得分:1)

auto always_false = [](double, double) {return false;}
std::function<bool(double,double)> checks = {
  always_false,
  less_equal<double>(),
  less<double>(), less<double>(),
  less_equal<double>(), less_equal<double>(),
  always_false
};

for( int i = 0; i < 7; ++i )
{
  if (checks[i]( 0, value ))
  {
    reportError(param);
    return;
  }
}

如果您的checks与上述一样简单并且没有状态,则可以将std::function<bool(double,double)>替换为原始函数指针bool(*)(double, double)。效率会不低。

解决这个问题的另一种方法是进行错误 - 不合时宜的编程。

boost::optional<ErrorMessage> err;
if (!err && test_1()) err = makeError(param);
if (!err && test_2()) err = makeError(param);
if (!err && test_3()) err = makeError(param);
// ...
if (err)
  reportError(*err);

代码流经测试,只有在先前的测试失败并报告错误时才会执行操作。