C ++逻辑&& amp;的短路评估和||运营商

时间:2016-03-10 14:07:08

标签: c++ c++11 operators short-circuiting

C ++中的用户重载逻辑运算符(&&, ||)的行为类似于常规函数。也就是说,bool operator&&(const T &a, const T2 &b);中的两个参数在进入函数之前都会被计算,因为输入函数是C ++中的序列点[1]。一切都好到这里。

现在,“内置运营商&&和||执行短路评估“[2] [3],其中左右两侧之间存在序列点。引用的参考文献并不清楚“内置”是什么,只是他们采用bool个操作数,或者使用“上下文转换为bool”将其转换。它还提到只有“两个标准库类重载这些运算符[因为]短路属性(...)不适用于重载,并且因为具有布尔语义的类型不常见。”[2]

具有布尔语义的类型? “内置运营商”究竟是如何运作的?是否根本无法通过短路评估来定义逻辑运算符?

[1] https://en.wikipedia.org/wiki/Sequence_point

[2] http://en.cppreference.com/w/cpp/language/operator_logical

[3] https://en.wikipedia.org/wiki/Short-circuit_evaluation

2 个答案:

答案 0 :(得分:2)

您可以想象短路&&的行为如下:

bool b = expr1 && expr2;

首先,它需要expr1expr2并将它们存储在lambdas中:

bool b = and_helper( [&]{return expr1;}, [&]{return expr2;} );

并将它们转发给帮助者,其中and_helper是(稍微简化):

template<class Lhs, class Rhs>
bool and_helper( Lhs&& lhs, Rhs&& rhs ) {
  if (lhs()) return rhs();
  return false;
}

这有类似的短路行为。

对于用户覆盖的&&以这种方式工作,我们必须自动lambda参数并将所述lambdas传递给用户编写的operator&&

因此,用户定义的操作发生这种情况的唯一障碍是语法。在对类型进行相对机械的转换之后,您可以获得相同的行为,而无需借助魔法。

当编译器遇到该构造时,编译器只执行了大致相同的操作(甚至在lambdas存在之前)。

答案 1 :(得分:0)

这意味着短路并不适用于用户定义的运营商。

这是因为,正如你所说,它们的行为类似于函数。