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

Simplify 4 if/else checks on two booleans

本文关键字:if 检查 else 布尔值 两个      更新时间:2023-10-16

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

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();

有没有办法简化/缩短这段代码? 提前感谢!

是的,你可以利用一些含义:

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一定为假,因此无需对其进行冗余评估。

由于学习是您的目的,因此使用查找表进行"简化":

#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

使用开关:

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

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

您始终可以在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]();

是的,您可以使用三元运算符:

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

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