Consider the following example:
struct Parent
{
Parent ();
Parent (const Parent &);
};
struct Child : public Parent
{
using Parent::Parent;
};
Parent p;
Child c (p);
This was taken from the following question: Why "an inherited constructor is not a candidate for initialization from an expression of the same or derived type"?
That original question asked about C++11. In C++11, there is wording that prevents Child
from acquiring a constructor that takes const Parent&
:
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.
N4429 significantly changed the specification of inheriting constructors and was considered retroactive to C++11 (I think?). The purpose of N4429 was to cause the base class constructors to be visible as if they were derived class constructors, rather than declaring derived class constructors that delegate to base class constructors. In the first version of N4429, there is the following wording, keeping the restriction from C++11:
When a using-declaration declares that a class inherits constructors from a base class, the default constructor, copy constructor, and move constructor (if any) of the base class are excluded from the set of introduced declarations.
However, in the updated version of this paper, P0136R0, this wording is no longer present, and no explanation is given as to why. The paper was revised once more and then merged into the standard. So in C++17, I cannot see any rule that would prevent the above code from compiling.
Nonetheless, GCC and Clang both reject it. Clang says:
an inherited constructor is not a candidate for initialization from an expression of the same or derived type
However, I cannot find anything in the standard that says anything like this.
Is this code ill-formed in C++17? And if so, why?
Copy constructor is not inherited.
This is all or nothing - you cannot inherit only some constructors, if you write this, you inherit all of them. To inherit only selected ones you need to write the individual constructors manually and call the base constructor as needed from them. Historically constructors could not be inherited in the C++03 standard.
A copy constructor is a member function that initializes an object using another object of the same class. In simple terms, a constructor which creates an object by initializing it with an object of the same class, which has been created previously is known as a copy constructor.
Hence, there is always one copy constructor that is either defined by the user or by the system.
[over.match.funcs]/8:
A constructor inherited from class type
C
([class.inhctor.init]) that has a first parameter of type “reference to cv1P
” (including such a constructor instantiated from a template) is excluded from the set of candidate functions when constructing an object of type cv2D
if the argument list has exactly one argument andC
is reference-related toP
andP
is reference-related toD
.
See CWG2356.
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