每个if-else构造都可以用等效的条件表达式替换吗?

时间:2009-11-30 07:39:46

标签: c++ c conditional-operator

(我不太需要这个答案,我只是好奇。)

每个if-else构造都可以使用条件运算符?:替换为等效的条件表达式吗?

8 个答案:

答案 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;

无法始终由?:运算符替换。您经常(如果不是总是)重新考虑您的整个代码以提供此替代,但通常您不能将控制执行的任何内容放入?:breakreturn,循环,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;
}

与使用程序(更自然)相比,这允许breakcontinuereturn等。它需要评估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>});