Redirect constructors reference the constructor of the 2-fold base class

The following code translates constructors from the base to the derived class.

Why two constructor calls? What happens in the background?

Compiled with g ++.

#include <iostream> using namespace std; struct A { A() { cout << "A" << endl; } A(const A&) { cout << "A(const A&)" << endl; } template<typename T> A(T a); // Needed to compile :-O }; template<typename T> struct C : public T { using T::T; }; int main() { A a; C<A> ca(a); //C<A> caa(ca); return 0; } 

Exit:

 A A(const A&) A(const A&) 
+7
c ++ constructor c ++ 11
source share
2 answers

By defining a constructor pattern in A , C will get a constructor pattern with a similar signature. It is implicitly defined in the same way:

 template<typename T> struct C : public T { //using T::T; C() = default; C(C const&) = default; template<typename U> C(U a) : T( std::forward<U>(a) ) {} }; 

Now it calls copy-constructor A twice: once to accept an argument by value. The second call comes from T( std::forward<U>(a) ) calling copy-ctor A This was surprising to me, since you were expecting the inherited ctor to call the exact ctor of the base class that was inherited. But this is not so, the overload resolution is not chosen by the ctor A template, but by the regular ctor A(A const&) instance A(A const&) (see below).


Interestingly, not everything that a constructor template does in A , it only needs to be declared. That is why the definition may not be in the OP; it can also be removed (what could be a defect?).

Copy-ctor A should only be selected if the initialization overload T( std::forward<U>(a) ) allowed T( std::forward<U>(a) ) . This is the case here: the argument is a rvalue of type A , which can be directly linked to a const A& link, as required by copy-ctor A. Since link-binding is direct and not derived, to-base conversion, copy-ctor takes place as exact conformity. The ctor template in A also evaluated as Exact match, but since there is a template function and not a template with the same rank in the overload set, a function without a template is preferred (copy-ctor A(A const&) ).

+6
source share

One call to A::A(const A&) is the constructor of the base class C<A> .

Another call is to copy the pass-by-value parameter.

+6
source share

All Articles