This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115e. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-11-19


2906. Lvalue-to-rvalue conversion of class types for conditional operator

Section: 7.6.16  [expr.cond]     Status: ready     Submitter: Jan Schultke     Date: 2024-06-08

(From submission #550.)

There are two known situations where the lvalue-to-rvalue conversion is applied to class types, which can be non-constexpr even if the resulting copy constructor invocation would be constexpr (7.7 [expr.const] bullet 5.9). The other such situation is 7.6.1.3 [expr.call] paragraph 11. Here, the concern is with 7.6.16 [expr.cond] paragraph 7, which can be invoked for class types; for example:

  struct S {};
  S a;
  constexpr S b = a;        // OK, call to implicitly-declared copy constructor
  constexpr S d = false ? S{} : a; // error: lvalue-to-rvalue conversion of 'a' is not a constant expression

Major implementations disagree with the ill-formed outcome.

Proposed resolution (approved by CWG 2024-06-26):

Change in 7.6.16 [expr.cond] paragraph 7 as follows:

Otherwise, the result is a prvalue. If the second and third operands do not have the same type, ...

Lvalue-to-rvalue (7.3.2 [conv.lval]), array-to-pointer Array-to-pointer (7.3.3 [conv.array]), and function-to-pointer (7.3.4 [conv.func]) standard conversions are performed on the second and third operands. After those conversions, one of the following shall hold: