Byłem w jakiś sposób zaskoczony, że poniższy kod kompiluje się i działa (vc2012 i gcc4.7.2)
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;
}
Czy to prawda, że ten kod kompiluje się dobrze? A dlaczego to prawda? Dlaczego mogę używać autona typie prywatnym, podczas gdy nie mogę używać jego nazwy (zgodnie z oczekiwaniami)?
privatejest to wygoda opisywania interfejsów API w sposób, który kompilator może pomóc w egzekwowaniu. Nie ma to na celu uniemożliwienia dostępu do typu Barprzez użytkowników Foo, więc nie utrudnia Foow żaden sposób oferowania tego dostępu przez zwrócenie wystąpienia Bar.
#include <iostream>. ;-)
f.Baz().ito również jest w porządku, tak jak jeststd::cout << typeid(f.Baz()).name(). Kod poza klasą „widzi” zwracany typ,Baz()jeśli możesz go zdobyć, po prostu nie możesz go nazwać.