If you're using braced-init-lists and the destination type of an initialization is a reference:
[dcl.init.list]/3 (from n3690)
Otherwise, if the initializer list has a single element of type
E
and eitherT
is not a reference type or its referenced type is reference-related toE
, the object or reference is initialized from that element; if a narrowing conversion (see below) is required to convert the element toT
, the program is ill-formed.Otherwise, if
T
is a reference type, a prvalue temporary of the type referenced byT
is copy-list-initialized or direct-list-initialized, depending on the kind of initialization for the reference, and the reference is bound to that temporary. [Note: As usual, the binding will fail and the program is ill-formed if the reference type is an lvalue reference to a non-const type. — end note]Otherwise, if the initializer list has no elements, the object is value-initialized.
For the two examples const A& c{1};
and const A& d = {1};
, the second bullet of the quotation above applies. The first one direct-list-initializes a const A
, the second one copy-list-initializes a const A
. Copy-initialization selecting an explicit
constructor is ill-formed, see [over.match.list]/1.
If you're not using braced-init-lists, there's no difference between copy-initialization and direct-initialization as far as I can tell. The last bullet of [dcl.init.ref]/5 applies in all cases:
- Otherwise, a temporary of type “cv1
T1
” is created and initialized from the initializer expression using the rules for a non-reference copy-initialization (8.5). The reference is then bound to the temporary.
Copy-initialization cannot select an explicit
ctor, see [over.match.copy]/1 (it's not viable).
Conclusion:
const A& c{1};
is legal. The other are not, because they either use copy-initialization or copy-list-initialization and the only viable / selected ctor is explicit
.