Copy initialization with deleted copy constructor in reference initialization

This issue is addressed by Issue 1604, and the proposed solution seems to confirm that such code should be ill-formed, so I would consider it as a compiler bug.

Fortunately, since C++17, this code becomes well-formed because of guaranteed copy elision, which agrees with the compilers.


Let's examine what the standard says:

Otherwise, a temporary of type T is constructed and copy-initialized from object. The reference is then bound to this temporary. Copy-initialization rules apply (explicit constructors are not considered).

So, a temporary of type T is constructed. This temporary is copy-initialized from the given object. OK... how does that work?

Well, you cited the rule explaining how copy-initialization from the given value will work. It will attempt to invoke user-defined conversions, by sifting through the applicable constructors of T and the conversion operators on the value (and there aren't any, since it is of type int). There is an implicit conversion constructor on T which takes an object of type int. So that constructor is called to initialize the object.

The reference is then bound to that temporary, per the rules you cited.

At no time is there any attempt to call any of the deleted functions. Just because it's called "copy-initialization" does not mean that a copy constructor will be called. It's called "copy-initialization" because it is (usually) provoked using an = sign, and therefore it looks like "copying".

The reason Data d = a; doesn't work is because C++11 defines this operation to first convert a into a Data temporary, then to initialize d with that temporary. That is, it's essentially equivalent to Data d = Data(a);. The latter initialization will (hypothetically) invoke a copy constructor, thus leading to the error.