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 ofBase
happens to have the signature that matches a copy/move constructor of theDerived
, it does not prevent implicit generation ofDerived
copy/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