懒惰,过载的C ++&&运营商?

时间:2013-04-16 08:07:34

标签: c++ boolean operator-keyword lazy-evaluation

我正在尝试实现自己的布尔类,但无法复制&&的本机语义。以下设计的代码演示了这个问题:



    #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;
}

编译并运行时,结果为:


    Native &&
       First
    Overloaded &&
       Second
       First

换句话说,&amp;&amp;在bools上是懒惰的(正如任何C ++程序员所期望的那样)但是过载的&amp;&amp;不是(因为这个C ++程序员至少没想到)。

有没有办法让重载&amp;&amp;懒?我可以找到各种全面的延迟评估方案来提供类似Haskell的功能,但是对于我的用例来说它们似乎完全有点过分。

4 个答案:

答案 0 :(得分:15)

你不应该重载bool operator&&,因为你已经发现了短路评估。

正确的方法是为您的班级提供一个bool转换运算符

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

请注意,显式转换运算符需要符合C ++ 11标准。如果您没有这个,请查看safe bool idiom

答案 1 :(得分:4)

  

有没有办法让重载&amp;&amp;懒惰?

没有

答案 2 :(得分:2)

您可以使用the expression template idiom进行几乎所有评估,包括但不限于内置版本短路的运算符。但是,这比你需要的工作更多,因为那时你的MyBool类需要批次更多的代码。

答案 3 :(得分:0)

如果您真的想要短路并愿意牺牲运算符语法,可以将operator&&方法重命名为_and,定义AND()宏,然后写{{1而不是AND(x,y)

x&&y

对于某些macro hacks,您可以#define AND(x,y) (x._and(x.theValue ? y : MyBool(false))) 接受可变数量的参数。

这里的AND()方法不打算在这里“公开”使用,但必须公开宣布,因为你不能_and()一个宏。

对于像friend类这样简单的事情,这可能是不必要的。但是,如果您需要MyBool具有特殊的副作用,例如更新operator&&上的某个状态,那么这可以完成工作。