I have the following code snippet:
struct A {};
struct B : A{};
B b{ A() };
Does the implicitly-declared copy constructor B::B(const B&) is used here so that the reference (const B&) is bound to B subobject of initialzier expression A()? and why no?
If this is an aggregate initialization, this means that the ctor B::B(const B&) is never called, so why when I explicitly deleted it, the program is ill-formed?
From C++17 onwards,
B b{ A() };is aggregate initialization.Prior C++17
Prior to C++17, the class-type
Bis not an aggregate. SoB b{ A() };cannot be aggregate initialization. In particular,B b{ A() };is direct initialization:(emphasis mine)
This means that all the implicitly declared ctors of
Bare considered but none of them can be used here. For example, the copy/move ctor cannot be used because they have a parameter of typeconst B&orB&&respectively and neither of those can be bound to the passedAobject as there is no way to implicitly convert anAtoBin your example. Thus the copy/move ctor cannot be used.Similarly, the default ctor
B::B()cannot be used because it has no parameter but we're passing anA.Thus this fails prior to c++17 with the error:
C++17
From C++17 onwards,
Bis an aggregate because it has public base class. This means, nowB b{ A() };is an aggregate initialization.