Oriol
Oriol

Reputation: 287990

Can I assign a value to a conditional expression in C++?

Is it valid to simplify this...

if (bool_b) {
    int_i1 = int_i3;
} else {
    int_i2 = int_i3;
}

..into the following?

(bool_b ? int_i1 : int_i2) = int_i3;

It seems to work on my compiler. But I think the draft C++11 standard: N3337 says it's invalid:

  • conditional-expression:
    • logical-or-expression
    • logical-or-expression ? expression : assignment-expression
  • assignment-expression:
    • conditional-expression
    • logical-or-expression assignment-operator initializer-clause
    • throw-expression

If I understand it well, the part at the left of = should be a logical-or-expression. But even though logical-or-expression are conditional-expressions, the reciprocal is false.

Upvotes: 2

Views: 126

Answers (2)

Christophe
Christophe

Reputation: 73366

Yes, it's valid if the two alternatives of the ternary operator are both lvalues of the same type.

N3242 5.16/4 : If the second and third operands are glvalues of the same value category and have the same type, the result is of that type and value category

The ternary operator is called conditional operator.

Gramar aspects:

The following gramar production :

conditional-expression:
    logical-or-expression
    logical-or-expression ? expression : assignment-expression

allow statements like:

true ? b : a = 20;      // yields b. if condition would be false, would yield a =20
true ? b = 11 : a = 21; // yields b=11 

As the gramar shows well the assignement would be limited to one of the branch

However, if we consider the full chain of gramar productions:

assignment-expression: 
    logical-or-expression assignment-operator initializer-clause
    ...
logical-or-expression:
    logical-and-expression
    logical-or-expression || logical-and-expression
logical-and-expression:
    inclusive-or-expression
    logical-and-expression && inclusive-or-expression
...  
primary-expression: 
    (expression) 
    ...  

So you could then write expressions like :

(true ? a : b) = 10;    // a and b are lvalues,  a or be are set to 10 depending on the condition

Upvotes: 5

aschepler
aschepler

Reputation: 72271

The parentheses are important partly because of the language detail you noticed. bool_b ? int_i1 : int_i2 is not a logical-or-expression, but (bool_b ? int_i1 : int_i2) is a primary-expression and therefore also a logical-or-expression.

Upvotes: 2

Related Questions