2012-12-18 2 views
14
struct B {}; 
struct D : private B { 
    B* fun() { return new D; } // ok 
} 
struct DD : public D { 
    B* foo() { return 0; } // error: ‘struct B B::B’ is inaccessible ! 
}; 

Dieser Fehler scheint mir unvernünftig. Wenn wir den einfachen B* im globalen Geltungsbereich verwenden können, warum nicht in seinen privat abgeleiteten Klassen? g++ demo.Warum ist eine einfache Erwähnung von Basiszeiger/Referenz in nachfolgenden privat abgeleiteten Klassen verboten?

Wir versuchen nicht DD*-B*, zu konvertieren, die von den Sprachregeln verboten ist (this, this, this sind Fragen).
Beachten Sie, dass, wenn ich B* foo() zu int foo() ändern, Dinge gut gehen.

+1

MSVC 10.0 beschwert sich mit dem gleichen Fehler. – Yuushi

+0

@Yuushi, behebt MSVC den Fehler mit [Pubbys Antwort] (http://stackoverflow.com/a/13927212/514235)?Ich wollte nur wissen, ob dies der Standard ist, um diesen "Bug" zu beheben. – iammilind

+0

Ja, kompiliert es mit ':: B *'. – Yuushi

Antwort

7

Also scheinbar der Compiler denkt B bezieht sich auf den privaten Konstruktor von B eher als der Typ.

Qualifikation B behebt anscheinend diesen Fehler:

class B* foo() { return 0; } 

oder dies:

::B* foo() { return 0; } 

Ich weiß nicht, warum das passiert ist, aber vielleicht wird dies dazu beitragen.


Update: vielleicht bezieht es sich auf 11.2.4 des Standards? Das einzige Problem ist, dass mein Standard nicht gut genug ist, um es vollständig zu verstehen.

(sorry für das Bild, Kopieren/Einfügen ist nicht für mich arbeiten)

+0

bedenkt man, dass 2 Compiler den gleichen Fehler auf 2 verschiedenen Plattformen melden, denke ich, dass das nur etwas mit dem Standard zu tun hat ein wichtiger Entwurf, wahrscheinlich über "Namensauflösung". – user1797612

+0

@ user1797612 Ja, ich stimme zu. – Pubby

7

Ein kurzer Blick-up für injiziert-class-name in den Standard-Ausbeuten lesen:

§11.1 [class.access.spec]

5/ [ Note: In a derived class, the lookup of a base class name will find the injected-class-name instead of the name of the base class in the scope in which it was declared. The injected-class-name might be less accessible than the name of the base class in the scope in which it was declared. —end note ]

[ Example:

class A { }; 
class B : private A { }; 
class C : public B { 
    A *p; // error: injected-class-name A is inaccessible 
    ::A *q; // OK 
}; 

—end example ]

Ich glaube, dies zu Ihrem Beispiel unheimlich nahe;)


Hinweis Klirren 3.0 Stack, der etwas deutlicher ist:

$ clang++ -fsyntax-only test.cpp 
test.cpp:6:5: error: 'B' is a private member of 'B' 
    B* foo() { return 0; } // error: ‘struct B B::B’ is inaccessible ! 
    ^
test.cpp:2:12: note: constrained by private inheritance here 
struct D : private B { 
      ^~~~~~~~~ 
test.cpp:1:8: note: member is declared here 
struct B {}; 
    ^
1 error generated. 

Hier sehen wir, dass B durch zugegriffen wird , statt direkt im globalen Namensraum abgeholt.

+0

+1: Das ist der eine :) –

Verwandte Themen