0

それで昨日私はこの質問をプライベートフレンドオペレーター<<operator<<クラスのためにプライベートに する方法について尋ねました。私は非常に良い答えを得て、それは私が望むように正確に機能しました、しかし私はそれについていくつかの追加の質問があります。

まず、プロキシクラスが友達である必要がないのはprivate_printableなぜですか?private_printable内部からの内部メンバーにアクセスするにはどうすればよいoperator<<ですか?

第二に、答えからのコードで遊んでいる間、私はこれを書きました:

operator proxy () const { return *this; }

最初は問題ないように見え、コンパイルもしましたが、実行してセグメンテーション違反が発生したとき、プロキシクラスのコンストラクターを定義していないことに気付きましたprivate_printable。これは引数として使用されるため、変換が可能になります。では、警告を出さずにコードをコンパイルするにはどうすればよいでしょうか。

private_printable次に、私が行った3番目のことは、変換演算子を定義する代わりに、引数として参照を持つコンストラクターをプロキシに与えることでした(明示的にはしませんでした)。を呼び出すことが再び可能であったことを除いて、すべてうまくいきoperator<< ましたprivate_printable。しかし、なぜこれが起こったのか、私にはよくわかりません。ADLのせいですか?私はそれについて漠然とした理解を持っていますが、そのすべての詳細についてはわかりません。とにかく、proxyクラスはプライベートですが、なぜADLが違いを生むのでしょうか。

4

1 に答える 1

1
  1. のであるため、のメンバーoperator<<にアクセスできます。のではありません。private_printablefriendprivate_printablefriendproxy

  2. return *thisオブジェクトを返しprivate_printableます。これは暗黙的にに変換する必要がありますproxy。に変換する方法private_printableproxy?を呼び出しprivate_printable::operator proxy ()ます。しかし、それは私たちがすでに行っている機能です!セグメンテーション違反は、無限再帰によるスタックオーバーフローが原因で発生します。その価値については、無限のループが別の可能な結果になります。

  3. explicitコンストラクターも変換関数であり、と同じ目的を果たしoperator proxyます。operator proxyADLは、コンストラクターが使用されていない場合と同じように、一種の関与があります。もちろん、解決策はコンストラクターを作成することexplicitです。そして、この問題は、コンストラクターの唯一のオペランドがプロキシー化されたクラスである特定の場合にのみ発生します。

メンバーであるproxyクラスは、private明示的に名前を付けた場合にのみ重要です。ADLは、引数を持つ関数を引き続き見つけることができproxyます。これにより、クラスタイプの使用はアクセス資格の影響を受けないため、変換関数へのアクセスが間接的に発生します。名前検索のみが影響を受けます。同様に、privateメンバータイプがある場合は、いつでもメンバータイプを使用できますtypedef

于 2013-03-27T13:02:32.100 に答える