性能
三元运算符的性能不应与编写良好的等效 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 等过于冗长而无法重复输入,创建命名临时变量可能会有所帮助,但是:
功能区别:统一结果类型
考虑:
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);
}
在上面的条件运算符版本中,1 经历了到double 的标准转换,以便匹配2.0 的类型,这意味着即使在true/1 情况下也会调用is(double) 重载。 if/else 语句不会触发此转换:true/1 分支调用 is(int)。
您也不能在条件运算符中使用整体类型为 void 的表达式,而它们在 if/else 下的语句中有效。
强调:需要价值的行动之前/之后的价值选择
有不同的重点:
if/else 语句首先强调分支,而要做的事情是次要的,而三元运算符强调要做什么而不是选择要使用的值。
在不同的情况下,两者都可以更好地反映程序员对代码的“自然”视角,使其更易于理解、验证和维护。您可能会发现自己根据在编写代码时考虑这些因素的顺序来选择一个而不是另一个 - 如果您已经开始“做某事”,那么您会发现您可能会使用几个(或几个)值中的一个来做? : 是表达这一点并继续您的编码“流程”的最少破坏性方式。