Reputation: 1804
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?
Upvotes: 3
Views: 103
Reputation: 170193
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.
Upvotes: 2