8

独自のブール クラスを実装しようとしていますが、&& のネイティブ セマンティクスを複製できません。次の不自然なコードは、この問題を示しています。



    #include <iostream>>

    class MyBool {
    public:
        bool theValue;
        MyBool() {}
        MyBool(bool aBool) {theValue = aBool;}
        MyBool operator&& (MyBool aBool) {return theValue && aBool.theValue;}
    };

    bool f1() {std::cout << "   First\n"; return false;}
    bool f2() {std::cout << "   Second\n"; return false;}

    int main(int argc, char** argv) {
        std::cout << "Native &&\n";
        f1() && f2();
        std::cout << "Overloaded &&\n";
        MyBool(f1()) && MyBool(f2());
        return 0;
}

コンパイルして実行すると、結果は次のようになります。

    ネイティブ &&
       初め
    オーバーロード &&
       2番
       初め

言い換えれば、bools の && は (C++ プログラマーが期待するように) 怠惰ですが、オーバーロードされた && はそうではありません (この C++ プログラマーは少なくとも予期していなかったように)。

オーバーロードされた && を怠惰にする方法はありますか? Haskell のような機能を提供するさまざまな完全な遅延評価スキームを見つけることができますが、私のユースケースでは完全にやり過ぎのように思えます。

4

4 に答える 4

15

bool operator&&あなたが発見したように、短絡評価を失うので、過負荷にしないでください。

正しいアプローチは、クラスに bool 変換演算子を与えることです

class MyBool {
 public:
  bool theValue;
  MyBool() {}
  MyBool(bool aBool) : theValue(aBool) {}
  explicit operator bool() { return theValue; }
};

明示的な変換演算子は C++11 に準拠する必要があることに注意してください。これを持っていない場合は、安全な bool イディオムを見てください。

于 2013-04-16T08:10:04.050 に答える
2

式テンプレート idiomを使用して、ほとんどすべてのものを遅延評価することができます。これには、組み込みバージョンが短絡する演算子が含まれますが、これに限定されません。しかし、これはこの 1 つのケースに必要な作業よりも多くの作業です。そうすると、MyBoolクラスにはさらに多くのコードが必要になるからです。

于 2013-04-16T09:29:40.187 に答える
0

本当にショートサーキットが必要で、演算子の構文を犠牲にしても構わないと思っている場合は、operator&&メソッドの名前を に変更し、マクロを_and定義して、代わりに.AND()AND(x,y)x&&y

#define AND(x,y) (x._and(x.theValue ? y : MyBool(false)))

いくつかのマクロ ハックAND()を使用すると、可変数のパラメーターを受け入れることができます。

ここでのメソッドは、ここで「パブリックに」使用することを意図していませんが、マクロを作成_and()できないため、パブリックとして宣言する必要があります。friend

クラスのように単純なものの場合MyBool、これはおそらく不要です。ただし、operator&&の状態を更新するなどの特別な副作用が必要な場合thisは、これで作業が完了します。

于 2016-01-01T15:21:11.173 に答える