Consider:
class A
{
protected:
A(int) {}
void f(int) {}
public:
A() {}
};
class B : public A
{
public:
using A::A;
using A::f;
};
int main()
{
B().f(1); // ok
B(1); // error: 'A::A(int)' is protected within this context
}
Why can't an inherited protected
constructor be made public
, while an inherited protected
member function can?
Unlike other members, the accessibility of the using-declaration that introduced the inherited constructor is ignored.
[namespace.udecl]/19,
(emphasis mine)
A synonym created by a using-declaration has the usual accessibility for a member-declaration. A using-declarator that names a constructor does not create a synonym; instead, the additional constructors are accessible if they would be accessible when used to construct an object of the corresponding base class, and the accessibility of the using-declaration is ignored.
Actually, the inherited constructor can be made public, but not just the way you wrote it. You can define your B
class as follows:
class B : public A {
public:
B() {}
B(int x) : A(x) {} // instead of using A::A(int)
using A::f;
};
(see it on GodBolt)
Perhaps the standard committee thought that saying using A::A
would be a bit ambiguous, since a constructor of the base class is not exactly the same thing as a constructor of the subclass.
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