Ram*_*mon 3 c++ operators short-circuiting c++11
C++ 中的用户重载逻辑运算符 ( &&, ||) 的行为类似于常规函数。也就是说,bool operator&&(const T &a, const T2 &b);在进入函数之前对 in 的两个参数进行求值,因为进入函数是 C++ 中的序列点[1]。到这里一切都很好。
现在, \xe2\x80\x9c 内置运算符 && 和 || 执行短路评估\xe2\x80\x9d [2][3],其中左侧和右侧之间有一个序列点。引用的参考文献并没有明确 \xe2\x80\x9cbuiltin\xe2\x80\x9d 是什么,只是它们接受bool操作数,或者使用 \xe2\x80\x9c 上下文转换为 bool\xe2\x80\ 将它们转换x9d。它还提到,只有 \xe2\x80\x9c 两个标准库类重载这些运算符,[因为]短路属性 (...) 不适用于重载,并且因为具有布尔语义的类型并不常见。\xe2\x80\ x9d [2]
具有布尔语义的类型?\xe2\x80\x9c 内置运算符\xe2\x80\x9d 到底如何工作?是否根本不可能用短路求值来定义逻辑运算符?
\n\n[1] https://en.wikipedia.org/wiki/Sequence_point
\n\n[2] http://en.cppreference.com/w/cpp/language/operator_logic
\n\n\n您可以想象短路的行为&&是这样的:
bool b = expr1 && expr2;
Run Code Online (Sandbox Code Playgroud)
首先,它接受expr1andexpr2并将它们存储在 lambda 中:
bool b = and_helper( [&]{return expr1;}, [&]{return expr2;} );
Run Code Online (Sandbox Code Playgroud)
并将它们转发给助手,其中and_helper(稍微简化):
template<class Lhs, class Rhs>
bool and_helper( Lhs&& lhs, Rhs&& rhs ) {
if (lhs()) return rhs();
return false;
}
Run Code Online (Sandbox Code Playgroud)
这具有类似的短路行为。
为了让用户覆盖以&&这种方式工作,我们必须自动 lambda 参数并将所述 lambda 传递到用户编写的operator&&.
因此,用户定义操作发生这种情况的唯一障碍是语法。在对类型进行相对机械的转换后,您可以获得相同的行为,而无需诉诸魔法。
当编译器遇到该构造时,它只是执行了大致相同的操作(甚至在 lambda 存在之前)。
| 归档时间: |
|
| 查看次数: |
1227 次 |
| 最近记录: |