If I understand correctly:
class Base { /*...*/ };
class Derived: public Base { public: using Base::Base; }
will enforce inheritance of all Base constructors in Derived.
But what about public/protected/private constructors?
class Base {
friend void g();
public:
Base (A a);
protected:
Base (B b);
private:
Base (C c);
};
class Derived: public Base {
public:
using Derived::Derived;
};
I can't find any specification on this, but I tried the following:
void f () {
Derived{A{}}; // OK
Derived{B{}}; // Inaccessible
Derived{C{}}; // Inaccessible
}
void g () {
Derived{A{}}; // OK
Derived{B{}}; // OK
Derived{C{}}; // OK
}
So it seems, that using Base::Base doesn't take the access modifiers into consideration when deciding which constructors to inherit (it inherits the private one) but it inherits them with those modifiers (private/protected ones remain inaccessible to others) and it allows private/protected access to friends of Base (friendship is not inherited, so g is not a friend of Derived, but it still can access private/protected constructor of Derived inherited from Base).
Is that correct and standard behaviour?
The specification you are looking for is in [namespace.udecl] ¶19, emphasis mine.
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.
Your testing is consistent with that paragraph. The accessibility checks fail or pass exactly as they would when constructing a Base in the scopes you check.
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