【发布时间】:2021-05-13 13:29:42
【问题描述】:
这是一个基于我给 here 的自我回答的自触发问题。
This 似乎非常令人信服地解释了为什么在 fold expressions 中可以使用逻辑运算符的短路,以及使用可变参数将折叠表达式包装在函数中这一事实似乎是非短路的(事实上,答案解释说,在短路发生在函数体内之前,是函数调用触发了所有参数的评估)。
但是,在我看来,以下代码证明(至少当折叠表达式中的参数为 2 时)不会发生短路:
#include <assert.h>
#include <optional>
constexpr auto all_r = [](auto const& ... ps){
return [&ps...](auto const& x){
return (ps(x) && ...);
};
};
constexpr auto all_l = [](auto const& ... ps){
return [&ps...](auto const& x){
return (... && ps(x));
};
};
constexpr auto has_value = [](std::optional<int> o){
return o.has_value();
};
constexpr auto has_positive = [](std::optional<int> o){
assert(o.has_value());
return o.value() > 0;
};
int main() {
assert(!(has_value(std::optional<int>{}) && has_positive(std::optional<int>{})));
//assert(!(has_positive(std::optional<int>{}) && has_value(std::optional<int>{}))); // expectedly fails at run-time
assert(!all_r(has_value, has_positive)(std::optional<int>{}));
assert(!all_l(has_value, has_positive)(std::optional<int>{})); // I expected this to fail at run-time
//assert(!all_r(has_positive, has_value)(std::optional<int>{}));
//assert(!all_l(has_positive, has_value)(std::optional<int>{})); // I expected this to succeed at run-time
}
【问题讨论】:
-
我不认为
ps(x) && ...或... && ps(x)对&&操作的关联性有任何改变。那么为什么要期待不同的行为呢? -
@prog-fh 这两种形式正是为了在一个方向或另一个方向上强加关联性。
-
但是只有两个参数会改变什么? (从三个开始,我看到了区别)我确实使用了不好的术语:不是关联性,而是评估顺序。
-
@prog-fh 我想我已经理解我的错误了。我错误地期望评估顺序在两种形式中被镜像,就像关联性被镜像一样。
标签: c++ c++17 lazy-evaluation short-circuiting fold-expression