13

次のようなクラスがあるとします。

class Foo
{
  std::vector<int> bar;

public:
  std::vector<int>& get_bar() { return bar; }
};

後で、と同じタイプの別の変数が必要になりますbar。私がこれを行うことができれば、それは私にとって理にかなっています:

decltype(Foo::bar) clone_of_bar;

しかし、それはうまくいきません。コンパイラは、'std :: vector <int> Foo::bar'はprivateであると教えてくれます。

だから私はこのようなものを使わなければならないことになります:

std::remove_reference<decltype(std::declval<Foo>().get_bar())>::type clone_of_bar;

これは機能しますが、完全な混乱のように見えます。たぶんそれを行うためのより簡単な方法があります。よくわかりません。しかし、私が本当に知りたいのは、なぜ私が単に使用できないのかということdecltype(Foo::bar)です。なぜ誰もbarがプライベートを気にする必要がありますか?実際に変数にアクセスしているわけではありません。

decltype言語の新機能です。なぜそれがプライベート変数で動作しないように設計されているのか理解できません。

4

3 に答える 3

18

言語弁護士の用語でbarは、は名前であり、decltype式で使用するには、コンパイラはアクセス制御を尊重する通常の名前検索を実行する必要があります。
なぜdecltype他の言語とは異なる方法で設計されるべきだったのでしょうか。なぜそれが例えばと一致してはならないのかについての説得力のある議論を提示していませんsizeof

クラスの作成者として、私はあなたがそのようなプライベートな実装の詳細を照会できるようにしたくありません。型をクラスの外で使用できるようにしたい場合は、それがどの型であるかを示すpublictypedefを定義します。

後で、同じタイプの別の変数が必要です。bar

プライベート実装の詳細と同じタイプの「別の変数」が必要ですか?したがって、クラスの作成者がFooコードをリファクタリングし、型を他の実装の詳細に置き換えると、コードの意味が突然変わり、無関係なコードが突然コンパイルを停止したり、サイレントに異なる動作をしたりする可能性があります。仕事。Fooそれは、プライベート実装の詳細と、作者が存在すら知らないかもしれない無関係なコードとの間の結合を導入するでしょう!それはひどい考えです。

于 2012-06-07T00:41:36.763 に答える
12

decltype(Foo::bar) 内部で動作しますFoo

外では、それが名前の付いたメンバーを持っているFooことを知っているはずがないので(つまり)、もちろんそれは機能しないはずです。Foobarprivate

于 2012-06-07T00:47:38.547 に答える
1

これはリリース4.8.0で修正されたgccのバグです。

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52816

于 2012-11-08T09:56:27.207 に答える