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,原因是
返回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);
}