【发布时间】:2013-04-08 13:10:49
【问题描述】:
我正在尝试实现我自己的布尔类,但无法为 && 复制本机语义。下面的人为代码演示了这个问题:
#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;
}
编译运行后,结果为:
本国的 && 第一的 重载 && 第二 第一的换句话说,布尔值上的 && 是惰性的(正如任何 C++ 程序员所期望的那样),但重载的 && 不是(至少这个 C++ 程序员没有预料到)。
有没有办法让重载的 && 变得懒惰?我可以找到各种完整的惰性求值方案来提供类似 Haskell 的功能,但对于我的用例来说,它们似乎完全是矫枉过正。
【问题讨论】:
-
懒惰是指短路。重载的运算符没有短路。
-
这个问题正是不建议重载
&&操作符的原因。 -
请注意,重载运算符不能短路的原因是
MyBool aBool作为参数传递给它。所以MyBool(f2())需要在operator&&的实现有机会运行之前计算。理论上,您可以编写一个模板operator&&重载,其RHS 是一个返回MyBool的函子。然后仅当 LHS 评估为真时才调用该函子。然后在 C++11 中,调用者可以编写一个 lambda:MyBool(f1()) && []() { return MyBool(f2()); }。但在实践中,不要这样做——当你必须在每次调用时明确指定惰性求值时,它是相当丑陋的。
标签: c++ boolean operator-keyword lazy-evaluation