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

新手上路,请多包涵

我正在浏览一些代码,并在其中发现了一些三元运算符。这段代码是我们使用的一个库,它应该很快。

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

你有什么经验?

原文由 hummingBird 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 886
2 个回答

表现

三元运算符的性能不应与写得很好的等价物 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 怪物吗?

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

  • To get performance matching ? : you may need to use std::move , except when the same temporary is passed to two && parameters in the函数调用:那么你必须避免它。这更复杂,更容易出错。

  • c ? x : y 评估 c 然后但不是 xy 两者之一,这使得可以安全地说测试指针不是 nullptr 之前使用0—它,同时提供一些后备价值/行为。该代码仅获得实际选择的 xy 中的任何一个的副作用。 With named temporaries, you may need if / else around or ? : inside their initialisation to prevent unwanted code executing, or code executing比期望的更频繁。

功能区别:统一结果类型

考虑:

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

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

    if (expr)
        is(1);
    else
        is(2.0);
}

In the conditional operator version above, 1 undergoes a Standard Conversion to double so that the type matched 2.0 , meaning the is(double) overload is甚至为 true / 1 情况调用。 The if / else statement doesn’t trigger this conversion: the true / 1 branch calls is(int) .

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

重点:需要价值的行动之前/之后的价值选择

有不同的重点:

if / else 语句首先强调分支,而要完成的工作是次要的,而三元运算符强调要完成的工作而不是选择要使用的值。

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

原文由 Tony Delroy 发布,翻译遵循 CC BY-SA 4.0 许可协议

您假设两者之间 必须 有区别,而事实上,有许多语言放弃了“if-else”语句而支持“if-else”表达式(在这种情况下,它们甚至可能不会有三元运算符,不再需要)

想象:

 x = if (t) a else b

无论如何,三元运算符是某些语言(C、C#、C++、Java 等)中 _没有_“if-else”表达式的表达式,因此它在那里 _发挥着独特的作用_。

原文由 user166390 发布,翻译遵循 CC BY-SA 2.5 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题