2014-07-06 4 views
18

Ich benutze Visual Studio 2012, und ich habe etwas gefunden, das irgendwie seltsam ist. Ich schreibe nicht etwas, das ich unbedingt benötigen, um über mehrere Compiler kompatibel zu sein, aber es kann später werden (wenn der Code ins Web gestellt wird, wollen die Benutzer keine Compilerfehler bekommen), aber ich möchte nicht schreiben etwas, das falsch oder einfach nicht nativ ist."Auto" Typ Abzug kompiliert, während expliziter Typ gibt Fehler

So ist dieser Testcode:

class A{ 
    class B{ 
     public: 
     int i; 
    }; 
    B myB; 
public: 
    B& getB() { return myB; } 
}; 

int main() 
{ 
    A a; 
    A::B& b = a.getB(); 
    auto& b2 = a.getB(); 
} 

Die erste Zeile in Haupt Pop error C2248: 'A::B' : cannot access private class declared in class 'A' wohingegen die zweite Leitung normalerweise kompiliert. Ich frage mich, soll Auto so funktionieren oder ist das ein weiterer Fehler in Visual Studio?

Ich habe keine andere Compiler kann ich es mit

testen auf Sie können sogar Sachen wie std::cout << b2.i << "\n"; schreiben und es kompiliert völlig in Ordnung

Per πάντα ῥεῖ Kommentar habe ich versucht, ideone mit gcc 4.8 .1 und es kompiliert auf die gleiche Weise, erste Zeile ist Fehler, zweite Zeile ist völlig in Ordnung.

+4

_'PS: Ich habe keinen anderen Compiler, den ich es mit '_ testen kann: http://isocpp.org/blog/2013/01/online-c-compilers besonders http://rise4fun.com/ vcpp –

+1

Interessant. Ich hatte nie über die Rechtmäßigkeit von so etwas nachgedacht, aber es scheint auch mit gcc und clang zu kompilieren. –

+0

Mit dem Code in 'main' zur Initialisierung von' b' und 'b2' führt die Ausgabeanweisung zu [* undefined behavior *] (http://en.wikipedia.org/wiki/Undefined_behavior) als' b' und ' b2' sind Verweise auf Objekte, die zerstört wurden –

Antwort

10

Ich glaube, es soll so funktionieren. Der Zugriff gilt für Namen, nicht für die Entitäten, auf die sie sich beziehen.

Sogar ohne auto war es immer legal, z.B. Übergeben Sie das Ergebnis von getB an eine Funktion, die eine B erwartet.

+1

Wenn Sie außerdem einen öffentlichen 'typedef' einer privaten Klasse erstellen, verursacht die Verwendung des' typedef''d-Namens bei der Verwendung des privaten Klassennamens keinen Fehler. – Frxstrem

+3

Oder ein typedef: http: //stackoverflow.com/questions/13532784/why-cani-i-use-auto-on-a-private-type – kobigurk

+0

re "Zugriff gilt für Namen, nicht die Entitäten, die sie beziehen", * Art von *. Zum Beispiel, C + 11 §12.1/1 "Konstruktoren haben keine Namen". Wohl Destruktoren haben auch keine Namen, und tatsächlich gibt es in C++ 11 zumindest eine (nicht-normative) Note, die so argumentiert. –

3

auto soll so funktionieren, ja, und ja, das bedeutet, dass es private Typen freilegen kann.