&&, || をオーバーロードするのは悪い考えですか? またはコンマ演算子となぜ?
7 に答える
オーバーロードしoperator&&
たり、operator||
. operator&
ブール代数 (有限集合など) を生成するクラスを定義したとしても、おそらくandをオーバーロードする方がよいでしょうoperator|
。
その理由は、C++ プログラマーが and に特別なセマンティクスを期待しoperator&&
ているからoperator||
です。これらは短絡されています。つまり、必要がなければ右側の引数を評価しません。関数を定義するため、オーバーロードによってこの動作を取得することはできません。
オーバーロードは、 Boost.Assignライブラリoperator,
などで行われています。これは、私が知っているオーバーロードの唯一の例でもあり、自分でオーバーロードすることを考えたことさえありません。他の演算子が適していない非常に具体的なユースケースを用意することをお勧めします。
C++ で論理演算子をオーバーロードするには、オペランドを評価する必要があります。これは、組み込み型のショート サーキットで通常動作する方法ではありません。
以下のリンクを見てください。
意外な方法で演算子をオーバーロードしないでください。:-)
(自分だけでなく)意味のある方法でそれを行うことができれば、そうすることは問題ありません。
他の人が言っているように、論理演算子は遅延評価の効果があるという点で特別です。したがって、オーバーロードは、式テンプレートのように、おそらくこの怠惰な効果を保持するか、人々がとにかくこの効果を期待しない場合にのみ使用する必要があります。
通常、これは悪い考えです。これら 3 つの演算子には、オーバーロードすると失われるシーケンス効果があります。そのシーケンス効果を失うと、それが失われることを予期していない人にアーム (つまり、奇妙なバグ) を引き起こす可能性があります。
テンプレート式を使用するとシーケンス効果を維持できる場合がありますが、そのような場合、それらをオーバーロードしても問題はないと思います。
operator,
私が知っているのオーバーロードには、別の問題があります。操作の明らかなチェーンが実際のものではないような方法で機能します。通常、それらは違いがない場合にコンテキストで使用されますが、ブルームーンになると、それが奇妙なバグの別の原因になります。
オーバーロードが何をしているかに依存すると思います。たとえば、&& および || 論理条件として機能することが期待されているため、オーバーロードのセマンティクスが何らかの形で異なるように機能する場合、他の人を混乱させる可能性があります (しばらく使用しないと、その動作を忘れてしまうと、自分自身でさえ) 混乱する可能性があります。オーバーロードされている方法がわからない場合、および代わりに通常のメソッドを使用する方が明確である場合に、オペレーターが何をすることを期待するかを検討してください。
他の人が言ったように、論理演算子のオーバーロードを避ける主な理由は、遅延評価の欠落です。
ただし、それらをオーバーロードする非常に正当な理由が 1 つあります:式テンプレートです。Boost.Lambda ライブラリはこれを行い、非常に便利です!
クラスが何らかの論理エンティティを表す場合を除いて、これは悪い考えです。オーバーロードされた演算子は方向性を失い、コードに新しいバグを引き起こす可能性があるためです。