C++ 每个if-else构造都可以被等价的条件表达式替换吗?
(我不太需要这个答案,我只是好奇。)C++ 每个if-else构造都可以被等价的条件表达式替换吗?,c++,c,conditional-operator,C++,C,Conditional Operator,(我不太需要这个答案,我只是好奇。) 是否可以使用条件运算符将每个if-else构造替换为等效的条件表达式?:?条件运算符希望?后面的两个项都是右值(因为条件运算符的结果本身就是右值)-因此,虽然我并不完全是C/C++标准方面的专家,但我的直觉是,以下内容是不允许的(或者,如果不允许的话,则是极差的编码风格……): 而if-else版本则相当标准: if(condition) return x; else return y; 现在,也就是说,你能接受任何一个程序并编写一个功能类似的程序,而不使
是否可以使用条件运算符将每个if-else构造替换为等效的条件表达式
?:
?条件运算符希望?
后面的两个项都是右值(因为条件运算符的结果本身就是右值)-因此,虽然我并不完全是C/C++标准方面的专家,但我的直觉是,以下内容是不允许的(或者,如果不允许的话,则是极差的编码风格……):
而if-else版本则相当标准:
if(condition) return x;
else return y;
现在,也就是说,你能接受任何一个程序并编写一个功能类似的程序,而不使用if-else吗?当然可以。但这并不意味着这是个好主意 使用条件运算符将生成表达式,并且条件运算符的两个潜在结果必须“兼容”(可转换为相同类型)
if
-else
构造甚至不需要“返回”任何类型,更不用说从两个分支返回相同的类型了。在它的表面上,不是。条件运算符是一个表达式(即,它有一个值),而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();
然而,话虽如此,我不确定这是否只是一种好奇
if( cond )
break;
else
a=b;
不能总是用?:
运算符替换。您可以经常(如果不是总是)重新思考整个代码以提供此替代,但通常不能将任何控制执行的内容放入?:
<代码>中断,返回
,循环,抛出
,等等
是否可以使用条件运算符将每个if-else构造替换为等效的条件表达式
不,你倒着问这个if/else的“主体”包含语句,不可能将每条语句都转换为表达式,例如try、while、break语句以及声明。然而,许多“陈述”实际上是伪装的表达:
++i;
blah = 42;
some_method(a,b,c);
所有这些语句都是由一个表达式(分别是增量、赋值和函数调用)组成的语句,可以在条件语句中转换为表达式
那么,让我们把问题反过来,因为听起来你真的想知道if/else语句与三元条件表达式的等价程度:每个条件表达式都能被等价的if/else语句替换吗?几乎所有,是的。一个常见的例子是返回语句:
return cond ? t : f;
// becomes:
if (cond) return t;
else return f;
还有其他表达方式:
n = (cond ? t : f);
// becomes:
if (cond) n = t;
else n = f;
if (<expression>)
<statement1>
else
<statement2>
它开始指向无法轻松替换条件表达式的地方:初始化。由于只能初始化对象一次,因此必须将使用条件的初始化分解为使用显式临时变量:
T obj (cond ? t : f);
// becomes:
SomeType temp;
if (cond) temp = t;
else temp = f;
T obj (temp);
请注意,这要繁琐得多,如果无法默认构造和分配某种类型,则需要依赖于类型的某种类型。GCC有
语句表达式
,使用它,您可以将if
语句重写为等效的?:
表达式:
n = (cond ? t : f);
// becomes:
if (cond) n = t;
else n = f;
if (<expression>)
<statement1>
else
<statement2>
原则上,是的:
if (A) B; else C
变成
try {
A ? throw TrueResult() : throw FalseResult();
// or: throw A ? TrueResult() : FalseResult();
} catch (TrueResult) {
B;
} catch (FalseResult) {
C;
}
与使用过程(更自然)相比,这允许
中断
,继续
,返回
等。它需要对进行评估
不会以真实结果
/假结果
结束,但如果您仅将这些异常用于模拟如果
,则不会有问题。否,当然不是。原因已经提到,还有更多
#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;
}
}
三元运算符不能做任何类似的操作。谢谢Dave,是的
(条件)?返回x:返回y不允许使用code>,原因是返回x
和返回y
不是表达式。条件表达式的语法是(expr1)?expr2:expr3
对于您建议的if-else构造,我认为这将是一个等价的条件表达式:return(condition)?X:y < /代码>是的,它是等价的,但这不是直接替换IF其他构造,它是代码的修改(因此是我的最后注释)。例如,考虑这一点:<代码> if(条件)返回x;否则y=2代码>-您将很难将其转换为三元代码在C和C++中,操作符称为条件算子。如果您正在搜索其他引用,您可能会发现这一点很有用。谢谢,我知道:)我确实搜索了其他引用,但没有找到我要查找的内容。请注意,还允许返回void类型的值。@hacker:Edited--谢谢您的提示。不知道条件子句中可能有一个空表达式!稍微偏离,此处不允许返回类型为void:int a=condition?if_block():else_block()代码>?(gcc 4.3.2)@James:这与被忽略的返回值如何摇摆?它有隐式int类型吗?@Drew:gcc说“错误:无效值不会被忽略,因为它应该被忽略”在我的例子中,但其他编译器可能只会发出警告?我认为应该在语句表达式周围加上void
之类的东西-强制转换操作不是在第二个和第三个操作数之间分配的。@litb:你能写一个我的void放置错误的简短例子吗?sambowry:在GCC 4.3.3中失败:echo'int main(){(空)(1({ ABC);}):({ 42;});}‘g++-xC++ +-c>代码>“I/OR”的“体”包含语句,不可能将每个语句转换成表达式“——这就消除了我的所有疑问。
if(HRESULT hr = myInterface->myMethod())
{
_com_raise_error(hr);
}