C++: Seltsame "privat" Fehler
Ich habe immer einen sehr ungewöhnlichen Fehler von g++ zu fordern, dass ein Typ-alias ist privat. Nach Stunden der Reduzierung meinem code habe ich kam auf die folgenden minimalen Testfall:
template <typename Dummy>
class Test {
struct CatDog {
static void meow ()
{
CrazyHouse::TheCatDog::meow();
}
struct Dog {
static void bark ();
};
};
struct CrazyHouse {
using TheCatDog = CatDog;
static void startMadness ()
{
TheCatDog::meow();
TheCatDog::Dog::bark();
}
};
public:
static void init ()
{
CrazyHouse::startMadness();
}
};
int main ()
{
Test<void> t;
t.init();
}
Den Fehler mit dem g++ 4.8.2 ist:
test.cpp: In instantiation of 'static void Test<Dummy>::CatDog::meow() [with Dummy = void]':
test.cpp:19:29: required from 'static void Test<Dummy>::CrazyHouse::startMadness() [with Dummy = void]'
test.cpp:27:34: required from 'static void Test<Dummy>::init() [with Dummy = void]'
test.cpp:34:12: required from here
test.cpp:15:33: error: 'using TheCatDog = struct Test<void>::CatDog' is private
using TheCatDog = CatDog;
^
test.cpp:6:41: error: within this context
CrazyHouse::TheCatDog::meow();
^
Clang 3.4 nimmt den gleichen code. Was ist denn hier Los, ist das eine g++ Fehler?
Tut jeder der folgenden Haltestellen der Fehler auftreten:
- Drehen
Test
in eine Klasse, im Gegensatz zu einem template-Klasse. - Entfernen von Anweisungen in jedem der den Funktionen.
- Ändern
TheCatDog::Dog::bark();
zuCatDog::Dog::bark();
. - Entfernen der
CrazyHouse
Klasse und die Zusammenführung Ihrer Inhalte inTest
. - Entfernen der
CatDog
Klasse, die Zusammenführung Ihrer Inhalte inTest
und die änderung derTheCatDog
alias zeigenTest
.
- Wahrscheinlich ja.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Name-lookup auf die Kennung
CatDog
findetTest::CatDog
erklärtprivate
. Der Zugang erfolgt vonCrazyHouse
, das ist nicht einfriend
vonTest
. Daher ist es illegal Zugang zu einem geschützten member.Als @sj0h Noten, die in C++11 Ihr Beispiel wird gültig, weil Sie beschlossen, um den Zugriff zu erweitern, um die Leichen von verschachtelten Klassen in der gleichen Weise wie member-Funktionen.
C++98:
C++11:
(Mitglieder haben das Recht auf Zugang
private
Mitglieder der umschließenden Klasse.)Jedoch diese änderung nicht angezeigt, umgesetzt werden in den GCC auch in einem aktuellen build der version 4.9. Also, um sicher zu sein, es kann nicht Schaden fügen Sie ein
friend
Erklärung. Das muss nach die definition des Elements:Beachten Sie, dass dies nicht erreichen, die genau das gleiche wie die C++11 zu ändern, weil
friend
Schiff ist nicht transitiv in der Erwägung, dass der Zugang gewährt verschachtelte Mitgliedschaft.Das Verhalten der Compiler als falsch oder rechts, je nachdem, welche version von C++, über die wir sprechen. Es scheint, dass das Verhalten von clang ist richtig, wenn wir reden über die C++11 und falsch, wenn wir sprechen über C++98.
Stackoverflow-Artikel C++ Zugriff auf die geschachtelte Klasse sollte klarstellen, dass.