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

2023-01-15


177. Lvalues vs rvalues in copy-initialization

Section: 9.4  [dcl.init]     Status: CD1     Submitter: Steve Adamczyk     Date: 25 October 1999

[Moved to DR at 4/02 meeting.]

Is the temporary created during copy-initialization of a class object treated as an lvalue or an rvalue? That is, is the following example well-formed or not?

    struct B { };
    struct A {
        A(A&);    // not const
        A(const B&);
    };
    B b;
    A a = b;

According to 9.4 [dcl.init] paragraph 14, the initialization of a is performed in two steps. First, a temporary of type A is created using A::A(const B&). Second, the resulting temporary is used to direct-initialize a using A::A(A&).

The second step requires binding a reference to non-const to the temporary resulting from the first step. However, 9.4.4 [dcl.init.ref] paragraph 5 requires that such a reference be bound only to lvalues.

It is not clear from 7.2.1 [basic.lval] whether the temporary created in the process of copy-initialization should be treated as an lvalue or an rvalue. If it is an lvalue, the example is well-formed, otherwise it is ill-formed.

Proposed resolution (04/01):

  1. In 9.4 [dcl.init] paragraph 14, insert the following after "the call initializes a temporary of the destination type":

    The temporary is an rvalue.
  2. In 14.2 [except.throw] paragraph 3, replace

    The temporary is used to initialize the variable...

    with

    The temporary is an lvalue and is used to initialize the variable...

(See also issue 84.)