Movatterモバイル変換


[0]ホーム

URL:


Issue 1571 - WG21 CWG Issues
Title
cv-qualification for indirect reference binding via conversion function
Status
cd4
Section
9.5.4 [dcl.init.ref]
Submitter
Michael Wong

Created on2012-02-06.00:00:00 last changed109 months ago

Messages

msg5384 (view)
Date: 2014-11-15.00:00:00

[Moved to DR at the November, 2014 meeting.]

msg4834 (view)
Date: 2014-02-15.00:00:00

Proposed resolution (February, 2014):

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

A reference to type “cv1T1” is initializedby an expression of type “cv2T2” asfollows:

  • If the reference is an lvalue reference...

  • Otherwise, the reference shall be an lvalue reference to anon-volatile const type...

    • If the initializer expression

      • is an xvalue (but not a bit-field), class prvalue, array prvalueor function lvalue and “cv1T1” isreference-compatible with “cv2T2”, or

      • has a class type (i.e.,T2 is a class type),whereT1 is not reference-related toT2, and can beconverted to an xvalue, class prvalue, or function lvalue of type“cv3T3”, where“cv1T1” is reference-compatible with“cv3T3” (see12.2.2.7 [over.match.ref]),

      then the reference is bound to the value of the initializer expressionin the first case and to the result of the conversion in the second case(or, in either case, to an appropriate base class subobject).In thesecond case, if the reference is an rvalue reference and the secondstandard conversion sequence of the user-defined conversion sequenceincludes an lvalue-to-rvalue conversion, the program is ill-formed.[Example:

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

      end example]

  • Otherwise:

    • IfT1orT2 is a classtypeandT1 is not reference-related toT2,user-defined conversions are considered using the rules forcopy-initialization of an object of type “cv1T1” by user-defined conversion (9.5 [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-referencecopy-initialization would be ill-formed. The result of the call to theconversion function, as described for the non-referencecopy-initialization, is then used to direct-initialize the reference.Theprogram is ill-formed if the direct-initialization does not result in adirect binding or if it involves a user-defined conversion.For this direct-initialization, user-defined conversions are notconsidered.

    • IfT1 is a non-class typeOtherwise,a temporary of type “cv1T1” is created andcopy-initialized (9.5 [dcl.init]) from the initializerexpression. The reference is then bound to the temporary.

    IfT1 is reference-related toT2:

    • cv1 shall be the same cv-qualification as, or greatercv-qualification than,cv2; and

    • if the reference is an rvalue reference, the initializer expressionshall not be an lvalue.

    [Example:

      struct Banana { };  struct Enigma { operator const Banana(); };  struct Alaska { operator Banana&(); };  void enigmatic() {    typedef const Banana ConstBanana;    Banana &&banana1 = ConstBanana(); // ill-formed    Banana &&banana2 = Enigma();      // ill-formed    Banana &&banana2 = Alaska();      // ill-formed  }  const double& rcd2 = 2;  //rcd2 refers to temporary with value2.0  double&& rrd = 2;        //rrd refers to temporary with value2.0  const volatile int cvi = 1;  const int& r2 = cvi;     // error: type qualifiers dropped  struct A { operator volatile int&(); } a;  const int& r3 = a;       // error: type qualifiers dropped from result of conversion function  double d2 = 1.0;  double&& rrd2 = d2;      // error:copyinginitializer is lvalue of related type  struct X { operator int&(); };  int && rri2 = X();       // error: result of conversion function is lvalue of related type  int i3 = 2;  double&& rrd3 = i3;      //rrd3 refers to temporary with value2.0

    end example]

This resolution also resolvesissue 1572.

msg4336 (view)
Date: 2013-04-15.00:00:00

Notes from the April, 2013 meeting:

CWG felt that the declaration ofir2a should also be an error.

msg4228 (view)
Date: 2012-02-06.00:00:00

In the case of indirect reference binding, 9.5.4 [dcl.init.ref] paragraph 5only requires that the cv-qualification of the referred-totype be the same or greater than that of the initializer expressionwhen the types are reference-related. This leads to the followinganomaly:

  class A {  public:    operator volatile int &();  };  A a;  const int & ir1a = a.operator volatile int&(); // error!  const int & ir2a = a; // allowed!ir = a.operator volatile int&();

Is this intended?

History
DateUserActionArgs
2017-02-06 00:00:00adminsetstatus: drwp -> cd4
2015-05-25 00:00:00adminsetstatus: dr -> drwp
2015-04-13 00:00:00adminsetmessages: +msg5384
2014-11-24 00:00:00adminsetstatus: ready -> dr
2014-03-03 00:00:00adminsetmessages: +msg4834
2014-03-03 00:00:00adminsetstatus: drafting -> ready
2013-05-03 00:00:00adminsetmessages: +msg4336
2013-05-03 00:00:00adminsetstatus: open -> drafting
2012-02-06 00:00:00admincreate

[8]ページ先頭

©2009-2026 Movatter.jp