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

2024-04-18


2704. Clarify meaning of "bind directly"

Section: 9.4.4  [dcl.init.ref]     Status: open     Submitter: Brian Bi     Date: 2022-11-11

Currently, 9.4.4 [dcl.init.ref] paragraph 5 specifies:

In all cases except the last (i.e., implicitly converting the initializer expression to the referenced type), the reference is said to bind directly to the initializer expression.

This is intended to refer to both sub-bullets of the last bullet (see issue 1604), but the presentation is unclear.

Suggested resolution:

  1. Change in 9.4.4 [dcl.init.ref] bullet 5.4 as follows:

    Otherwise, the reference is said to bind indirectly to the initializer expression:
    • If T1 or T2 is a class type and T1 is not reference-related to T2, user-defined conversions are considered using the rules for copy-initialization of an object of type “cv1 T1” by user-defined conversion (9.4 [dcl.init], 12.2.2.5 [over.match.copy], 12.2.2.6 [over.match.conv]); the program is ill-formed if the corresponding non-reference copy-initialization would be ill-formed. The result of the call to the conversion function, as described for the non-reference copy-initialization, is then used to direct-initialize the reference. For this direct-initialization, user-defined conversions are not considered.
    • Otherwise, the initializer expression is implicitly converted to a prvalue of type “T1”. The temporary materialization conversion is applied, considering the type of the prvalue to be “cv1 T1”, and the reference is bound to the result.
    If T1 is reference-related to T2:
    • cv1 shall be the same cv-qualification as, or greater cv-qualification than, cv2; and
    • if the reference is an rvalue reference, the initializer expression shall not be an lvalue. [Note 3: This can be affected by whether the initializer expression is move-eligible (7.5.4.2 [expr.prim.id.unqual]). —end note]
  2. Change in 9.4.4 [dcl.init.ref] paragraph 5 as follows:

    In all cases except the last (i.e., implicitly converting the initializer expression to the referenced type), the The reference is said to bind directly to the initializer expression if it does not bind indirectly. [ Example:
      struct S {
        operator int();
      };
      struct T {
        T(int);
      };
      int&& r1 = S(); // binds directly
      T&& r2 = int(); // binds indirectly
      int&& r3 = double(); // binds indirectly
    
    -- end example ]