开发者

Can every if-else construct be replaced by an equivalent conditional expression?

开发者 https://www.devze.com 2022-12-12 16:51 出处:网络
(I don\'t have a seriou开发者_开发百科s need for this answer, I am just inquisitive.) Can every if-else construct be replaced by an equivalent conditional expression using the conditional operator ?:

(I don't have a seriou开发者_开发百科s need for this answer, I am just inquisitive.)

Can every if-else construct be replaced by an equivalent conditional expression using the conditional operator ?:?


Does every if-else constructs can be replaced by an equivalent conditional expression using conditional operator?

No, you've asked this backwards. The "bodies" of if/else contain statements, and it is not possible to turn every statement into an expression, such as try, while, break statements, as well as declarations. Many "statements" are really expressions in disguise, however:

++i;
blah = 42;
some_method(a,b,c);

All of these are statements which consist of one expression (increment, assignment, function-call, respectively) and could be turned into expressions within a conditional.

So, let's reverse the question, since it sounds like you really want to know how equivalent if/else statements are to ternary conditional expressions: Can every conditional expression be replaced by equivalent if/else statements? Almost all, yes. A common example is return statements:

return cond ? t : f;
// becomes:
if (cond) return t;
else return f;

But also other expressions:

n = (cond ? t : f);
// becomes:
if (cond) n = t;
else n = f;

Which starts to point to where conditional expressions cannot be easily replaced: initializations. Since you can only initialize an object once, you must break up an initialization that uses a conditional into using an explicit temporary variable instead:

T obj (cond ? t : f);
// becomes:
SomeType temp;
if (cond) temp = t;
else temp = f;
T obj (temp);

Notice this is much more tedious/cumbersome, and requires something type-dependent if SomeType cannot be default-constructed and assigned.


On the surface of it, no. The conditional operator is an expression (that is, it has a value), while if/else is a statement (thus has no value). They fulfill different "needs" within the language syntax.

However, since you can ignore expression values, and since any expression can be turned into a statement by adding a semicolon, you can essentially emulate if/else with a conditional expression and two auxiliary functions:

// 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();

However, having said that, I'm not sure it's anything more than a curiosity...


No, of course not. For reasons already mentioned, and more!

#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;
    }
}

Check out where is is declared. It's not an often used technique, but it can be used in situations like COM where every call returns HRESULT which is (almost always) zero on success (S_OK), non-zero on failure, so you might write something like:

if(HRESULT hr = myInterface->myMethod())
{
    _com_raise_error(hr);
}

The ternary operator can't do anything analogous.


if( cond )
    break;
else
    a=b;

can not always be replaced by ?: operator. You can often (if not always) rethink your whole code to provide for this substitute, but generally you can't put anything that controls execution into ?:. break, return, loops, throw, etc.


In principle, yes:

if (A) B; else C

becomes

try {
  A ? throw TrueResult() : throw FalseResult();
  // or: throw A ? TrueResult() : FalseResult();
} catch (TrueResult) {
  B;
} catch (FalseResult) {
  C;
}

Compared to using procedures (which are more natural), this allows break, continue, return etc. It requires evaluation of A doesn't end with TrueResult/FalseResult but if you use those exceptions only to simulate if, it won't be a problem.


Using the conditional operator results in an expression and both potential results of the conditional operator must be 'compatible' (convertible to the same type).

An if-else construct need not even 'return' any type much less the same one from both branches.


The conditional operator expects to have both of the items following the ? be rvalues (since the result of a conditional operator is itself an rvalue) - so while I'm not entirely an expert on the C/C++ standards, my intuition would be that the following would be disallowed (or failing that, extremely poor coding style...):

(condition) ? return x : return y;

whereas the if-else version would be quite standard:

if(condition) return x;
else return y;

Now, that said, could you take any program and write a similarly functioning program that didn't use if-else? Sure, you probably could. Doesn't mean it would be a good idea, though. ;)


GCC has statement expression, using it you can rewrite if statements to equivalent ?: expressions:

if (<expression>)
  <statement1>
else
  <statement2>

EDIT: The void casts serves two purpose. The subexpressions in ?: must have the same type, and without the void cast the compiler may print warning: statement with no effect.

(<expression>)? (void)({<statement1>}) : (void)({<statement2>});
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号