Why and when does the ternary operator return an lvalue?

Both i and j are glvalues (see this value category reference for details).

Then if you read this conditional operator reference we come to this point:

4) If E2 and E3 are glvalues of the same type and the same value category, then the result has the same type and value category

So the result of (i < 3) ? i : j is a glvalue, which can be assigned to.

However doing something like that is really not something I would recommend.


The rules for this are detailed in [expr.cond]. There are many branches for several combinations of types and value categories. But ultimately, the expression is a prvalue in the default case. The case in your example is covered by paragraph 5:

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 and it is a bit-field if the second or the third operand is a bit-field, or if both are bit-fields.

Both i and j, being variables names, are lvalue expressions of type int. So the conditional operator produces an int lvalue.