1
votes

§8.5.3[dcl.init.ref]/5 bullet point (5.2.2.1):

Emphases are mine

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 userdefined conversion (8.5, 13.3.1.4, 13.3.1.5); 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.

1

1 Answers

2
votes

This was an addendum to the standard to address an issue with the discarding of cv-qualifiers through indirect reference binding of a class with user-defined conversions.

The pertinent defect is 1571.

The example given was this:

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&();

The first reference initialization is invalid, as it discards cv-qualifiers from the initializer expression. However, under the old rules, the second was valid, as only the cv-qualifiers on the converted object were considered, not those of the reference returned by the conversion operator.

I think your confusion arises from the two possible conversions. User-defined conversions are considered to see if they could copy-initialize a non-reference of cv1 T1, then the result of that conversion is used to direct-initialize the reference, for which user-defined conversions are not considered.