(我不是很需要这个答案,我只是好奇。)
是否可以使用条件运算符将每个 if-else 构造替换为等效的条件表达式?:
?
是否可以使用条件运算符将每个 if-else 构造替换为等效的条件表达式?
不,你是倒过来问的。 if/else 的“主体”包含语句,不可能将每个语句都变成一个表达式,例如 try、while、break 语句以及声明。然而,许多“陈述”实际上是变相的表达:
++i;
blah = 42;
some_method(a,b,c);
所有这些都是由一个表达式(分别为增量、赋值、函数调用)组成的语句,并且可以转换为条件内的表达式。
所以,让我们把问题反过来,因为听起来你真的很想知道 if/else 语句与三元条件表达式的等效性:每个条件表达式都可以被等效的 if/else 语句替换吗? 几乎所有,是的。一个常见的例子是 return 语句:
return cond ? t : f;
// becomes:
if (cond) return t;
else return f;
但也有其他表达:
n = (cond ? t : f);
// becomes:
if (cond) n = t;
else n = f;
这开始指向条件表达式不能轻易替换的地方:初始化。由于您只能初始化一个对象一次,因此您必须将使用条件的初始化分解为使用显式临时变量:
T obj (cond ? t : f);
// becomes:
SomeType temp;
if (cond) temp = t;
else temp = f;
T obj (temp);
请注意,这更加乏味/繁琐,并且如果 SomeType 无法默认构造和分配,则需要依赖于类型的东西。
从表面上看,没有。条件运算符是一个表达式(即它有一个值),而 if/else 是一个语句(因此没有值)。它们满足语言语法中的不同“需求”。
但是,由于您可以忽略表达式值,并且由于可以通过添加分号将任何表达式转换为语句,因此您基本上可以使用条件表达式和两个辅助函数来模拟 if/else:
// Original code:
if (condition) {
// block 1
}
else {
// block 2
}
// conditional expression replacement:
bool if_block() {
// block 1
return true;
}
bool else_block() {
// block 2
return true;
}
// Here's the conditional expression. bool value discarded:
condition ? if_block() : else_block();
但是,话虽如此,我不确定这只是出于好奇……
不,当然不。由于已经提到的原因,还有更多!
#include <cstdlib>
#include <iostream>
int main()
{
if(int i = std::rand() % 2)
{
std::cout << i << " is odd" << std::endl;
}
else
{
std::cout << i << " is even" << std::endl;
}
}
查看声明的位置。这不是一种经常使用的技术,但它可以用于像 COM 这样的情况,其中每个调用都返回 HRESULT,它(几乎总是)成功时为零(S_OK),失败时非零,所以你可以写如下内容:
if(HRESULT hr = myInterface->myMethod())
{
_com_raise_error(hr);
}
三元运算符不能做任何类似的事情。
条件运算符希望两个项目都?
位于右值之后(因为条件运算符的结果本身就是一个右值) - 所以虽然我并不完全是 C/C++ 标准的专家,但我的直觉是以下将被禁止(或失败,极差的编码风格......):
(condition) ? return x : return y;
而 if-else 版本将非常标准:
if(condition) return x;
else return y;
现在,就是说,你能用任何程序编写一个功能相似但不使用 if-else 的程序吗?当然,你可能可以。但这并不意味着这将是一个好主意。;)
使用条件运算符会产生一个表达式,并且条件运算符的两个潜在结果必须是“兼容的”(可转换为相同的类型)。
一个if
-else
构造甚至不需要从两个分支“返回”任何类型,更不用说相同的类型了。
if( cond )
break;
else
a=b;
不能总是由?:
操作员代替。您可以经常(如果不是总是)重新考虑您的整个代码以提供此替代品,但通常您不能将任何控制执行的内容放入?:
. break
, return
, 循环throw
, 等等。
原则上,是的:
if (A) B; else C
变成
try {
A ? throw TrueResult() : throw FalseResult();
// or: throw A ? TrueResult() : FalseResult();
} catch (TrueResult) {
B;
} catch (FalseResult) {
C;
}
与使用过程(更自然)相比,这允许break
,continue
等return
。它需要评估A
不以TrueResult
/结尾,FalseResult
但如果您仅使用这些异常来模拟if
,则不会有问题。
GCC 有statement expression
,使用它你可以将语句重写if
为等价的?:
表达式:
if (<expression>)
<statement1>
else
<statement2>
编辑:void
演员有两个目的。中的子表达式?:
必须具有相同的类型,并且没有强制转换void
编译器可以打印warning: statement with no effect
.
(<expression>)? (void)({<statement1>}) : (void)({<statement2>});