I expected this to work
struct Parent
{
Parent ();
Parent (const Parent &);
};
struct Child : public Parent
{
using Parent::Parent;
};
Parent p;
Child c (p);
Child inherits all of Parent's constructors, right?
Including Parent::Parent(const Parent &)?
x.cpp:15:11: error: no matching function for call to ‘Child::Child(Parent&)’
Child c (p);
^
x.cpp:5:2: note: candidate: Parent::Parent(const Parent&)
Parent (const Parent &);
^~~~~~
x.cpp:10:16: note: inherited here
using Parent::Parent;
^~~~~~
x.cpp:10:16: note: an inherited constructor is not a candidate for initialization from an expression of the same or derived type
x.cpp:8:8: note: candidate: Child::Child()
struct Child : public Parent
^~~~~
Why can't I construct a Child from a Parent?
This is essentially CWG issue 2356: Base class copy and move constructors should not be inherited.
[over.match.funcs]/p9 now says:
A constructor inherited from class type C ([class.inhctor.init]) that has a first parameter of type “reference to cv1 P” (including such a constructor instantiated from a template) is excluded from the set of candidate functions when constructing an object of type cv2 D if the argument list has exactly one argument and C is reference-related to P and P is reference-related to D.
Inheriting a constructor doesn't prevent the default copy constructor of Child from being generated by the compiler.
This implies that you have a Child::Child(const Child&) which is hiding the inherited constructor that can't be chosen by lookup resolution, as cppreference.com explains:
if an inherited constructor matches the signature of one of the constructors of Derived, it is hidden from lookup by the version found in
Derived. If one of the inherited constructors ofBasehappens to have the signature that matches a copy/move constructor of theDerived, it does not prevent implicit generation ofDerivedcopy/move constructor (which then hides the inherited version, similar to using operator=).
In §12.9 of C++11 ISO standard is it stated:
For each non-template constructor in the candidate set of inherited constructors other than a constructor having no parameters or a copy/move constructor having a single parameter, a constructor is implicitly declared with the same constructor characteristics unless there is a user-declared constructor with the same signature in the class where the using-declaration appears.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With