C++逻辑&&和||运营商
Short-circuit evaluation on C++ logical && and || operators
用户重载逻辑运算符在C++(&&, ||
)中的行为类似于常规函数。也就是说,bool operator&&(const T &a, const T2 &b);
中的两个参数在进入函数之前都要被计算,因为输入函数是C++中的一个序列点[1]。到这里都很好。
现在,"内置运算符 && 和 ||执行短路评估" [2][3],其中左右两侧之间有一个序列点。引用的参考文献并不清楚"内置"是什么,只是它们采用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
想象短路&&
是这样的:
bool b = expr1 && expr2;
首先,它采用expr1
和expr2
并将它们存储在 lambda 中:
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参数并将所述lambda传递给用户编写的operator&&
。
因此,用户定义的操作发生这种情况的唯一障碍是语法。 在对类型进行相对机械的转换后,您可以获得相同的行为,而无需诉诸魔法。
编译器在遇到该构造时只是执行了大致等效的操作(甚至在 lambda 存在之前)。
这意味着短路不适用于用户定义的运算符。
这是因为,正如你所说,它们的行为类似于函数。
- 呼叫运营商<<临时
- 两个运营商的一些奇怪的冲突<<
- 如何在 CPP 中访问家长的运营商
- 如何明确调用好友流运营商
- 私有运营商删除会触发 GCC 和 Clang 的编译时错误,但不会在 MSVC 上触发编译时错误
- 使用运营商New分配的数据结构是否有任何副作用
- "Inheriting"移动运营商?
- 朋友ostream&运营商<<无法访问私人会员
- 为什么在下面的代码返回类型中是用于运营商重载的类类型
- 范围的枚举(枚举类)关系运营商
- 为什么“操作员”需要const但不是为“运营商&lt;”
- 对这两个分配运营商之间的不同感到困惑
- 我的班级意外加法运营商
- OpenACC - C++"新"运营商问题
- c 对运营商的一致性是新的,有多少重要
- 为什么我不能使私人运营商成为新的并使用默认实现?
- 全球取代所有新运营商
- 包装C 朋友在Cython中的非会员运营商
- 合法的交换运营商的模板实施
- C++逻辑&&和||运营商