Same question is asked: Why does GCC allow inheriting from a private nested class? For non template classes, its allowed to inherit from private nested classes, if it is a friend, but not for template classes. Is it a bug?
template<class Base>
class InheritFromBaseMember : public Base::MemberPrivate // error
{
using PrivateMember = typename Base::MemberPrivate; // works fine
};
class MyBase{
friend class InheritFromBaseMember<MyBase>;
// another try to declare it friend
template<class T>
friend class InheritFromBaseMember;
friend class AnotherClass;
class MemberPrivate{};
};
class AnotherClass : public MyBase::MemberPrivate{}; // works fine
int main() {
InheritFromBaseMember<MyBase>{};
}
Errormessage from g++ 5.3.0:
error: 'class MyBase::MemberPrivate' is private
class MemberPrivate{};
^
error: within this context
class InheritFromBaseMember : public Base::MemberPrivate // error
^
A nested class may inherit from private members of its enclosing class. The following example demonstrates this: class A { private: class B { }; B *z; class C : private B { private: B y; // A::B y2; C *x; // A::C *x2; }; }; The nested class A::C inherits from A::B .
If the declaration of a nested class is followed by the declaration of a friend class with the same name, the nested class is a friend of the enclosing class.
Nested Classes in C++ A nested class is a class that is declared in another class. The nested class is also a member variable of the enclosing class and has the same access rights as the other members. However, the member functions of the enclosing class have no special access to the members of a nested class.
This is definitely a gcc bug. gcc has lots of issues with friendship and templates. This example almost exactly appears in the standard, under [class.friend], emphasis mine:
Declaring a class to be a friend implies that the names of private and protected members from the class granting friendship can be accessed in the base-specifiers and member declarations of the befriended class.
[ Example:class A { class B { }; friend class X; }; struct X : A::B { // OK: A::B accessible to friend A::B mx; // OK: A::B accessible to member of friend class Y { A::B my; // OK: A::B accessible to nested member of friend }; };
—end example ]
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