0

I read inheriting constructors question and I broadly understand c++ constructor inheritance.

class X;

class A {
    A(const A& a); // (1)
    A(const X& x); // (2)
};

class B : A {
    using A::A;
}

Copy constructors are specials so I cannot use (1) to build a B from an A although I can use (2) to build a B form an X;

However I can add a templated constructor in B:

template<class...T> B(T... t) : A(t...) {}

This templated constructor will allow to build a B form an A.

I want to know what are the side effects of this method and what constructors does it effectively defines ?

For instance, can I move an A to a B this way. Do I still need the using A::A declaration in B? Do I need to add some std::forward black magic?

Guillaume Gris
  • 2,135
  • 17
  • 34
  • Note that `template B(T... t)` is not copy constructor. and even with `T&&`, but in later case, you can have exact match over default copy constructor (`B b(non_const_b);`). – Jarod42 Nov 16 '17 at 12:04

1 Answers1

1

what are the side effects of this method and what constructors does it effectively defines ?

It defines only one template c'tor. Its specializations will attempt to initialize A with whatever values you give it.

For instance, can I move an A to a B this way.

You aren't forwarding. Since you pass by value, even an explicit B b{std::move(a)}; will not move the argument into the A base.

Do I still need the using A::A declaration in B?

You may have it. It won't be ambiguous, since non-templates are favored over templates when doing overload resolution. That inherited c'tor will be used in B b{std::move(a)}; instead (since a const reference can bind to an xvalue). Essentially, the overload being picked may not always be what you want.

Do I need to add some std::forward black magic?

For the template c'tor? Definitely. Use forwarding references by default. And naturally std::forward to do the job of forwarding.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
  • Ok, so now I use forwarding but on Visual studio 2017, the compiler tries to resolve the default constructor with the template declaration witch fails on std::forward<>. So I have to add B() = default. It works fine on GCC. Considering all this, It seems that I need three lines to do a "complete inheritance" of constructors. Does it seem right to you? – Guillaume Gris Nov 16 '17 at 11:10
  • @GuillaumeGris - Visual studio is notoriously non-conforming when templates are concerned. GCC is in the right, but you'll need that extra for MSVC. – StoryTeller - Unslander Monica Nov 16 '17 at 11:12