Ich war irgendwie überrascht, dass der folgende Code kompiliert und ausgeführt (vc2012 & gcc4.7.2)Warum kann ich auto für einen privaten Typ verwenden?
class Foo {
struct Bar { int i; };
public:
Bar Baz() { return Bar(); }
};
int main() {
Foo f;
// Foo::Bar b = f.Baz(); // error
auto b = f.Baz(); // ok
std::cout << b.i;
}
Ist es richtig, dass dieser Code kompiliert fein? Und warum ist es richtig? Warum kann ich auto
auf einer privaten Art verwenden, während ich seinen Namen nicht (wie erwartet) nicht verwenden kann?
Beachten Sie, dass 'f.Baz() I' auch in Ordnung ist, wie' std :: cout << typeid (f.Baz()). name() '. Code außerhalb der Klasse kann den von "Baz()" zurückgegebenen Typ "sehen", wenn Sie ihn erreichen können, Sie können ihn einfach nicht benennen. –
Und wenn Sie denken, dass es komisch ist (was Sie wahrscheinlich tun, wenn Sie sehen, wie Sie danach fragen), sind Sie nicht der einzige;) Diese Strategie ist sehr nützlich für Dinge wie den [Safe-Bool Idiom] (http: // www .artima.com/cppsource/safebool.html). –
Ich denke, die Sache zu erinnern ist, dass 'private' ist es als Annehmlichkeit für APIs in einer Art und Weise zu beschreiben, die die Compiler erzwingen helfen können. Es ist nicht von den Benutzern von 'foo' zu verhindern, den Zugang zu der Art 'Bar' vorgesehen, so dass er nicht behindert 'foo' in keiner Weise aus, dass der Zugang bietet durch eine Instanz von' Bar' zurück. –