HighCommander4
HighCommander4

Reputation: 52739

Conditional expression with class type lvalue operands

I'm trying to figure out what should be the value category of the result of a conditional expression if its second and third operands are lvalues of class type.

Example:

struct S {};
S x, y;
void foo(bool cond) {
  cond ? x : y;  // what is the value category of the result?
}

I'm seeing two different paragraphs in [expr.cond] say different things.

According to paragraph 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

This paragraph seems to apply, and say that the result is an lvalue, because the second and third operands are both lvalues of the same type.

According to paragraph 6, however:

Lvalue-to-rvalue, array-to-pointer, and function-to-pointer standard conversions are performed on the second and third operands. After those conversions, one of the following shall hold:

  • The second and third operands have the same type; the result is of that type. If the operands have class type, the result is a prvalue temporary of the result type, which is copy-initialized from either the second operand or the third operand depending on the value of the first operand.

This paragraph also seems to apply, and say that the result of the expression is an rvalue.

So which is it - lvalue or rvalue? Are the two paragraphs really contradicting each other, or am I missing something subtle?

Upvotes: 1

Views: 94

Answers (1)

Brian Bi
Brian Bi

Reputation: 119099

You have to read the paragraphs in order, and select the first that applies. Emphasis mine.

1

...

2

If either the second or the third operand has type void ...

3

Otherwise, if the second and third operand have different types and either has (possibly cv-qualified) class type, or if both are glvalues of the same value category and the same type except for cv-qualification ...

4

If the second and third operands are glvalues of the same value category and have the same type ...

5

Otherwise, the result is a prvalue. If the second and third operands do not have the same type, and either has (possibly cv-qualified) class type, overload resolution is used to determine the conversions (if any) to be applied to the operands (13.3.1.2, 13.6). If the overload resolution fails, the program is ill-formed. Otherwise, the conversions thus determined are applied, and the converted operands are used in place of the original operands for the remainder of this section.

6

Lvalue-to-rvalue (4.1), array-to-pointer (4.2), and function-to-pointer (4.3) standard conversions are per- formed on the second and third operands. ...

Upvotes: 4

Related Questions