Title
Direct initialization vs “implicit” conversion in reference binding
Status
c++14
Section
9.4.4 [dcl.init.ref]
Submitter
Daniel Krügler

Created on 2011-04-06.00:00:00 last changed 113 months ago

Messages

Date: 2013-09-15.00:00:00

[Moved to DR at the September, 2013 meeting.]

Date: 2013-04-15.00:00:00

Proposed resolution (April, 2013):

Change the two indicated (not contiguous) sub-bullets of 9.4.4 [dcl.init.ref] paragraph 5 as follows:

  • has a class type (i.e., T2 is a class type), where T1 is not reference-related to T2, and can be implicitly converted to an lvalue of type “cv3 T3,”...

  • has a class type (i.e., T2 is a class type), where T1 is not reference-related to T2, and can be implicitly converted to an xvalue, class prvalue, or function lvalue of type “cv3 T3”, where “cv1 T1” is reference-compatible with “cv3 T3(see 12.2.2.7 [over.match.ref]),

Date: 2013-04-15.00:00:00

Note from the April, 2013 meeting:

Because of concerns about slicing and performance in the February, 2012 proposed resolution, CWG decided to return to the August, 2011 proposed resolution and split off the discussion about class prvalues into issue 1650.

Date: 2012-02-15.00:00:00

Proposed resolution (February, 2012) [SUPERSEDED]:

  1. Change 9.4.4 [dcl.init.ref] paragraph 5 as follows:

  2. A reference to type “cv1 T1” is initialized by an expression of type “cv2 T2” as follows:

    • If the reference is an lvalue reference and the initializer expression

      • is an lvalue (but is not a bit-field), and “cv1 T1” is reference-compatible with “cv2 T2,” or

      • has a class type (i.e., T2 is a class type), where T1 is not reference-related to T2, and can be implicitly converted to an lvalue of type “cv3 T3,” where “cv1 T1” is reference-compatible with “cv3 T3106 (this conversion is selected by enumerating the applicable conversion functions (12.2.2.7 [over.match.ref]) and choosing the best one through overload resolution (12.2 [over.match])),

      then the reference is bound...

    • Otherwise, the reference shall be...

      • If the initializer expression

        • is an xvalue, class prvalue, array prvalue or function lvalue and “cv1 T1” is reference-compatible with “cv2 T2”, or

        • has a class type (i.e., T2 is a class type), where T1 is not reference-related to T2, and can be implicitly converted to an xvalue, class prvalue, or function lvalue of type “cv3 T3”, where “cv1 T1” is reference-compatible with “cv3 T3(see 12.2.2.7 [over.match.ref]),

        then the reference is bound... [Example:

          struct A { };
          struct B : A { } b;
          extern B f();
          const A& rca2 = f();    // bound to the A subobject of the B rvalue.
          A&& rra = f();          // same as above
          struct X {
            operator B();
            operator int&();
          } x;
          const A& r = x;         // bound to the A subobject of the result of the conversion
          int i2 = 42;
          int&& rri = static_cast<int&&>(i2); // bound directly to i2
          B&& rrb = x;            // bound directly to the result of operator B
          int&& rri2 = X();       // error: lvalue-to-rvalue conversion applied to the
                                  // result of operator int&
        

        end example]

      • Otherwise, a temporary... [Example:

      •   const A& r = x;         // r refers to a temporary
          B&& rrb = x;            // rrb refers to a temporary
        
          const double& rcd2 = 2; // rcd2 refers to temporary with value 2.0
          double&& rrd = 2;       // rrd refers to temporary with value 2.0
          ...
        
  3. Change 12.2.2.7 [over.match.ref] paragraph 1 as follows:

  4. Under the conditions specified in 9.4.4 [dcl.init.ref], a reference can be bound directly to a glvalue or class prvalue that is the result of applying a conversion function...

    • The conversion functions of S and its base classes are considered, except that for copy-initialization, only the non-explicit conversion functions are considered. Those that are not hidden within S and yield type “lvalue reference to cv2 T2” (when 9.4.4 [dcl.init.ref] requires an lvalue result) or cv2 T2” or “rvalue reference to cv2 T2” (when 9.4.4 [dcl.init.ref] requires an rvalue result), where “cv1 T” is reference-compatible (9.4.4 [dcl.init.ref]) with “cv2 T2”, are candidate functions.

Date: 2012-09-24.00:00:00

Additional note, January, 2012:

Questions have been raised regarding the consistency of the treatment of class prvalues in this resolution with other types . The issue is thus being returned to "review" status for additional discussion.

Date: 2011-08-15.00:00:00

Proposed resolution (August, 2011) [SUPERSEDED]:

Change the two indicated (not contiguous) sub-bullets of 9.4.4 [dcl.init.ref] paragraph 5 as follows:

  • has a class type (i.e., T2 is a class type), where T1 is not reference-related to T2, and can be implicitly converted to an lvalue of type “cv3 T3,”...

  • has a class type (i.e., T2 is a class type), where T1 is not reference-related to T2, and can be implicitly converted to an xvalue, class prvalue, or function lvalue of type “cv3 T3”, where “cv1 T1” is reference-compatible with “cv3 T3(see 12.2.2.7 [over.match.ref]),

Date: 2012-09-24.00:00:00

In 9.4.5 [dcl.init.list] paragraph 5, both the cases in which a reference can be bound to the result of a conversion function use the phrase “can be implicitly converted to...” This is confusing, as it could be read as excluding explicit conversion functions. However, that appears not to be the intent, as 12.2.2.7 [over.match.ref], which is cited in these cases, allows explicit conversion functions for direct-initialization.

History
Date User Action Args
2014-11-24 00:00:00adminsetstatus: drwp -> c++14
2014-03-03 00:00:00adminsetstatus: dr -> drwp
2013-10-14 00:00:00adminsetmessages: + msg4689
2013-10-14 00:00:00adminsetstatus: ready -> dr
2013-05-03 00:00:00adminsetmessages: + msg4313
2013-05-03 00:00:00adminsetmessages: + msg4312
2013-05-03 00:00:00adminsetstatus: review -> ready
2012-09-24 00:00:00adminsetmessages: + msg3889
2012-02-27 00:00:00adminsetmessages: + msg3757
2012-01-17 00:00:00adminsetmessages: + msg3602
2012-01-17 00:00:00adminsetstatus: ready -> review
2011-04-06 00:00:00admincreate