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ć auto
na typie prywatnym, podczas gdy nie mogę używać jego nazwy (zgodnie z oczekiwaniami)?
private
jest 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 Bar
przez użytkowników Foo
, więc nie utrudnia Foo
w żaden sposób oferowania tego dostępu przez zwrócenie wystąpienia Bar
.
#include <iostream>
. ;-)
f.Baz().i
to 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ć.