Sono stato in qualche modo sorpreso che il seguente codice compilato ed eseguito (vc2012 & gcc4.7.2)Perché posso utilizzare l'auto su un tipo privato?
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;
}
È vero che questo codice compila bene? E perché è corretto? Perché posso usare auto
su un tipo privato, mentre non posso usare il suo nome (come previsto)?
Si osservi che 'f.Baz() I' è anche OK, come è' std :: cout << typeid (f.Baz()). name() '. Il codice al di fuori della classe può "vedere" il tipo restituito da 'Baz()' se riesci a prenderlo, non puoi chiamarlo. –
E se pensi che sia strano (cosa che probabilmente fai, visto che te lo chiedi) non sei l'unico;) Questa strategia è molto utile per cose come [Safe-Bool Idiom] (http: // www .artima.com/cppsource/safebool.html) però. –
Penso che la cosa da ricordare sia che 'private' è lì come una comodità per descrivere le API in un modo che il compilatore può aiutare a far rispettare. Non ha lo scopo di impedire l'accesso al tipo 'Bar' da parte degli utenti di' Foo', quindi non ostacola 'Foo' in alcun modo dall'offrire quell'accesso restituendo un'istanza di' Barra'. –