(我不太需要这个答案,我只是好奇。)
每个if-else构造都可以使用条件运算符?:
替换为等效的条件表达式吗?
答案 0 :(得分:11)
是否每个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不能默认构造和分配,则需要依赖于类型的东西。
答案 1 :(得分:4)
表面上看,没有。条件运算符是一个表达式(即,它有一个值),而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();
然而,话虽如此,我不确定这只不过是一种好奇心......
答案 2 :(得分:2)
不,当然不是。由于已经提到的原因,还有更多!
#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);
}
三元运算符不能做任何类似的事情。
答案 3 :(得分:1)
条件运算符期望?
之后的两个项都是rvalues(因为条件运算符的结果本身就是rvalue) - 所以虽然我不完全是C / C ++的专家标准,我的直觉是不允许以下内容(或者失败,编码风格极差......):
(condition) ? return x : return y;
而if-else版本非常标准:
if(condition) return x;
else return y;
现在,那说,你能不能使用任何程序并编写一个不使用if-else的类似功能的程序?当然,你可能会。但这并不意味着它会是一个好主意。 ;)
答案 4 :(得分:1)
使用条件运算符会产生一个表达式,条件运算符的两个潜在结果必须是“兼容的”(可转换为相同的类型)。
if
- else
构造甚至不需要“返回”任何类型,而不是两个分支中的相同类型。
答案 5 :(得分:1)
if( cond )
break;
else
a=b;
无法始终由?:
运算符替换。您经常(如果不是总是)重新考虑您的整个代码以提供此替代,但通常您不能将控制执行的任何内容放入?:
。 break
,return
,循环,throw
等
答案 6 :(得分:1)
原则上,是的:
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
并不以{结尾{ {1}} / TrueResult
但如果您仅使用这些例外来模拟FalseResult
,则不会出现问题。
答案 7 :(得分:0)
GCC有statement expression
,使用它可以将if
语句重写为等效的?:
表达式:
if (<expression>)
<statement1>
else
<statement2>
编辑:void
演员表有两个目的。 ?:
中的子表达式必须具有相同的类型,如果没有void
强制转换,编译器可能会打印warning: statement with no effect
。
(<expression>)? (void)({<statement1>}) : (void)({<statement2>});