三元运算符与IF语句的优点

2022-02-21 00:00:00 if-statement conditional-operator c++

我正在浏览一些代码,发现其中有几个三元运算符。此代码是我们使用的库,并且应该相当快。

我在想,除了那里的空间,我们是否节省了任何东西。

您有什么经验?


解决方案

性能

三元运算符的性能不应与编写良好的等效if/else语句不同.它们可以很好地解析为抽象语法树中的相同表示,经历相同的优化等。

只能使用?:

执行的操作

如果要初始化常量或引用,或计算要在成员初始化列表中使用哪个值,则不能使用if/else语句,但可以使用?:语句:

const int x = f() ? 10 : 2;

X::X() : n_(n > 0 ? 2 * n : 0) { }

简明代码的因子分解

使用?:的主要原因包括本地化,以及避免重复相同语句/函数调用的其他部分,例如:

if (condition)
    return x;
else
    return y;

.只比.更可取

return condition ? x : y;
如果与非常缺乏经验的程序员打交道,或者某些术语足够复杂以至于?:结构在噪音中迷失,则基于可读性的原因使用?:。在更复杂的情况下,如:

fn(condition1 ? t1 : f1, condition2 ? t2 : f2, condition3 ? t3 : f3);

等效if/else

if (condition1)
    if (condition2)
        if (condition3)
            fn(t1, t2, t3);
        else
            fn(t1, t2, f3);
    else if (condition3)
            fn(t1, f2, t3);
        else
            fn(t1, f2, f3);
else
    if (condition2)
       ...etc...

这是编译器可能优化也可能不优化的大量额外函数调用。

此外,?允许您选择一个对象,然后使用其成员:

(f() ? a : b).fn(g() ? c : d).field_name);

等效的if/else将为:

if (f())
    if (g())
        x.fn(c.field_name);
    else
        x.fn(d.field_name);
else
    if (g())
        y.fn(c.field_name);
    else
        y.fn(d.field_name);

命名的临时对象无法改进上面的if/Else怪物吗?

如果表达式t1f1t2等过于冗长而无法重复键入,创建命名的临时文件可能会有所帮助,但是:

  • 若要获得性能匹配?:,可能需要使用std::move,除非将相同的临时函数传递给调用的函数中的两个&&参数:则必须避免使用。这更复杂,也更容易出错。

  • ?x:y评估c,然后评估x和y,代码仅获得实际选择的x和y中任何一个的副作用。对于命名的临时文件,您可能需要在其初始化周围或内部使用if/else?:,以防止不需要的代码执行,或者代码执行的频率超过预期。

功能差异:统一结果类型

考虑:

void is(int) { std::cout << "int
"; }
void is(double) { std::cout << "double
"; }

void f(bool expr)
{
    is(expr ? 1 : 2.0);

    if (expr)
        is(1);
    else
        is(2.0);
}
在上面的条件运算符版本中,1经过标准转换为double,以便匹配的类型与2.0匹配,这意味着即使在true/1情况下也会调用is(double)重载。if/else语句不会触发此转换:true/1分支调用is(int)

您也不能在条件运算符中使用总体类型为void的表达式,而它们在if/else下的语句中有效。

强调:需要值的操作之前/之后的值选择

重点不同:

anif/else语句首先强调分支,其次是要执行的操作,而三元运算符强调在选择要执行分支的值时要执行的操作。

在不同的情况下,两者都可以更好地反映程序员对代码的"自然"观点,并使其更易于理解、验证和维护。您可能会发现,您在编写代码时根据考虑这些因素的顺序选择其中一个-如果您已经开始"做某事",那么您可能会使用几个(或几个)值中的一个来完成,?:是表达这一点并继续编码"流"的破坏性最小的方式。

相关文章