2016-05-27 17 views
8

Die gleiche Frage wird gestellt: Warum erlaubt GCC Erben von einer privaten geschachtelten Klasse? Bei Nicht-Template-Klassen darf es von privaten verschachtelten Klassen erben, , wenn es ein Freund ist, aber nicht für Template-Klassen. Ist es ein Fehler?Warum erlaubt GCC das Erben von einer privaten geschachtelten Klasse nicht, wenn Sie ein Freund sind?

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>{}; 
} 

Fehlermeldung von g ++ 5.3.0:

error: 'class MyBase::MemberPrivate' is private 
    class MemberPrivate{}; 
     ^
error: within this context 
class InheritFromBaseMember : public Base::MemberPrivate // error 
    ^
+1

Sind Sie über die Compiler-Version sicher? Es kompiliert [hier] (https://godbolt.org/g/1uUkge) ganz gut mit g ++ 4.9.0 und höher, einschließlich 5.3.0. Aber nicht mit früheren Versionen. – user2079303

+0

Nun, ich übersetze mit Eclipse/CDT Cygwin Diverses - Version und die Ausgabe ist: g ++ (GCC) 5.3.0 – gerdi

Antwort

5

Dies ist definitiv ein gcc Fehler. gcc hat lots of issues mit Freundschaft und Vorlagen. Dieses Beispiel fast genau in der Norm erscheint, unter [class.friend], Hervorhebung von mir:

eine Klasse Deklarieren impliziert ein Freund zu sein, dass die Namen von privaten und geschützten Mitglieder aus der Klasse Gewährung Freundschaft sein kann Zugriff in der Basis-Bezeichner und Mitglied Erklärungen der befreundeten Klasse.
[Beispiel:

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 
    }; 
}; 

-Ende Beispiel]