次のコードがコンパイルされて実行されることになんとなく驚いた(vc2012&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;
}
このコードが正常にコンパイルされることは正しいですか?そして、なぜそれが正しいのですか?auto
名前を(期待どおり)使用できないのに、プライベートタイプで使用できるのはなぜですか?
そして、それが奇妙だと思う場合(おそらくそうするでしょう、あなたがそれについて尋ねているのを見て)、あなただけではありません;)この戦略は、Safe-Boolイディオムなどの場合に非常に役立ちます。
—
Matthieu M.
覚えておかなければならないのは
—
Steve Jessop、
private
、コンパイラーが強制できるようにAPIを説明するのに便利であることです。これBar
はFoo
、のユーザーによるタイプへのアクセスを防ぐことを目的としていないためFoo
、のインスタンスを返すことによってそのアクセスを提供することを妨げるものではありませんBar
。
「このコードが正しくコンパイルされることは正しいですか?」いいえ
—
LF
#include <iostream>
。;-)
f.Baz().i
でも問題ないことを確認しますstd::cout << typeid(f.Baz()).name()
。クラスの外のコードは、Baz()
それを手に入れることができ、名前を付けることができない場合に、返されるタイプを「見る」ことができます。