In this piece of code, why is A's constructor with no parameters not inherited? Is there a special rule that prevents inheriting constructors with no parameters?
struct A {
A(void *) {}
A() {}
};
class B : public A {
public:
using A::A;
B(int x) {}
};
void f() {
B b(1);
B b2(nullptr);
B b3; // error
}
clang++ -std=c++11 gives this error, and g++ -std=c++11 gives a substantially similar error message:
td.cpp:15:7: error: no matching constructor for initialization of 'B'
B b3; // error
^
td.cpp:9:5: note: candidate constructor not viable: requires single argument 'x', but no arguments
were provided
B(int x) {}
^
td.cpp:8:14: note: candidate constructor (inherited) not viable: requires 1 argument, but 0 were
provided
using A::A;
^
td.cpp:2:5: note: inherited from here
A(void *) {}
A constructor that takes no parameters is called a parameterless constructor. Parameterless constructors are invoked whenever an object is instantiated by using the new operator and no arguments are provided to new .
Default Constructor – A constructor that accepts no parameter is called Default Constructor. It is not necessary to have a constructor block in your class definition. If you don't explicitly write a constructor, the compiler automatically inserts one for you.
A derived class cannot have a constructor with default parameters.
As the earlier example shows, it is possible to inherit from a base class with no constructors defined. It is not possible for a class to have no constructors. In your earlier example, the base class contains no explicit constructors, so it therefore defines the default public parameterless constructor.
The relevant information is in 12.9 [class.inhctor] paragraph 3 (the highlighting is added):
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 complete class where the using-declaration appears. [...]
That is, default constructor are not inherited unless they have a [defaulted] argument. If they have a default argument they are inherited but without the defaulted argument as is pointed out by a node on the same paragraph:
Note: Default arguments are not inherited. [...]
Basically, that says that default constructors are not inherited.
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