whacko__Cracko
whacko__Cracko

Reputation: 6692

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

(I don't have a serious need for this answer, I am just inquisitive.)

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

Upvotes: 8

Views: 7200

Answers (8)

Amber
Amber

Reputation: 526613

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. ;)

Upvotes: 1

Michael Burr
Michael Burr

Reputation: 340218

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.

Upvotes: 1

Drew Hall
Drew Hall

Reputation: 29055

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...

Upvotes: 4

Roger Pate
Roger Pate

Reputation:

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.

Upvotes: 11

DrPizza
DrPizza

Reputation: 18340

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.

Upvotes: 2

sambowry
sambowry

Reputation: 2466

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

Upvotes: 0

sdcvvc
sdcvvc

Reputation: 25654

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.

Upvotes: 1

Michael Krelin - hacker
Michael Krelin - hacker

Reputation: 143091

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.

Upvotes: 1

Related Questions