简化对两个布尔值的 4 if/else 检查

Simplify 4 if/else checks on two booleans

我的代码中有这样的情况:

bool a, b, result;
... // a and b are set
if(!a &&! b)
    result = functionOne() ;
else if(!a && b)
    result = functionTwo();
else if(a &&! b)
    result = functionThree();
else
    result = functionFour();

有什么方法可以simplify/shorten这段代码吗? 提前致谢!

是的,你可以利用一些暗示:

bool a, b, result;
... // a and b are set
if(a && b)
    result = functionFour();
else if(b)
    result = functionTwo();
else if(a)
    result = functionThree();
else
    result = functionOne();

解释:如果ab不是都为真,则一定有一个为假。在这种情况下,如果 b 为真,则 a 必须 为假,因此无需对其进行冗余计算。

学习是你的目的,这里是 "simplification" 使用查找 table:

#include <iostream>

bool functionOne()
{
  std::cout << __FUNCTION__ << std::endl;
  return true;
}
bool functionTwo()
{
  std::cout << __FUNCTION__ << std::endl;
  return true;
}
bool functionThree()
{
  std::cout << __FUNCTION__ << std::endl;
  return true;
}
bool functionFour()
{
  std::cout << __FUNCTION__ << std::endl;
  return true;
}

int main()
{
  using F = bool (*)();
  constexpr F lookup[2][2] = {{functionOne, functionTwo},
                              {functionThree, functionFour}};

  bool a = true, b = false, result;
  result = lookup[a][b]();           // <- the simplification
}

打印:

functionThree

符合预期。

说明:它使用了一个函数指针的二维数组。

注意: 它按照 C++ 标准明确表示在转换 bool -> int(您的数组索引)期间,false 转换为零,true 转换为 1。

If the source type is bool, the value false is converted to zero and
the value true is converted to the value one of the destination type
(note that if the destination type is int, this is an integer
promotion, not an integer conversion).

https://en.cppreference.com/w/cpp/language/implicit_conversion

这个问题实际上是基于意见的,因此有许多可能的解决方案 - 取决于个人喜好 - 可以选择。

你总是可以在if中测试单个变量,然后使用三元运算符

 if (!a)
     result = (!b) ? functionOne() : functionTwo();
 else
     result = (!b) ? functionThree() : functionFour();

这有一个(可能的)优势,即只需要在 运行 时间对 !a!b 分别求值一次。

如果你想消除否定(有些人可能认为这对可读性更好,特别是因为函数名称暗示它们的顺序是不常见的)代码可以变成

 if (a)
     result = b ? functionFour() : functionThree();
 else
     result = b ? functionTwo() : functionOne();

这给我们带来了完全消除 if 语句的选项。

 // with negation

 result = !a ? ((!b) ? functionOne() : functionTwo()) : 
              ((!b) ? functionThree() : functionFour());

 // without negation

 result = a ? (b ? functionFour() : functionThree()) : 
              (b ? functionTwo() : functionOne());

想到的另一个选择是

 int index = 2*a + b;
 if (index == 0)
     result = functionOne();
 else if (index == 1)
     result = functionTwo();
 else if (index == 2)
     result = functionThree();
 else if (index == 3)
     result = functionFour();

可以用一维数组简化

  using func = bool(*)();    // C++11 and later.   typedef bool (*func)() for all C++ standards
  func table[] = {functionOne, functionTwo, functionThree, functionFour};
  result = table[2*a + b]();

是的,您可以使用 ternary operator:

bool a, b, result;
// a and b are set
result = a && b ? functionOne() : b ?functionTwo() : a ? functionThree() : functionFour();

仅将它用于简单的 if else 任务,而不用于复杂的任务,因为它很快就会变得混乱。

使用开关:

 int index = 2*a + b;
 switch (index) {
     case 0: result = functionOne();  break;
     case 1: result = functionTwo();  break;
     case 2: result = functionThree();break;
     case 3: result = functionFour(); break;
 }