c++ - 折叠表达式中的短路

标签 c++ c++17 lazy-evaluation short-circuiting fold-expression

这是一个基于我给出的 self 回答的 self 触发问题 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) 具有四个谓词 a, b, c, d 扩展为

( ( a(x) && b(x) ) && c(x) ) && d(x)

这导致了这样的评估顺序:a b c d

ps(x) && ... 扩展为

a(x) && ( b(x) && ( c(x) && d(x) ) )

这会导致相同的求值顺序:a b c d

这不会改变有关短路的任何内容;一旦有错误,评估就停止。

关于c++ - 折叠表达式中的短路,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66127093/

相关文章:

c++ - OpenCV findContours 问题

c++ - 函数在 C++17 中变成 noexcept?

c++ - 在赋值运算符函数中,数组是否隐式为 memcpy

c++ - 将原始内存数组 (char*) 的内容传递给 std::istream& 参数而不复制缓冲区内容?

spring - 如何不允许从跨国方法之外延迟加载?

Scala编译问题 "forward reference extends over definition of value"

c++ - 以编程方式检测按键的更好方法?

c++ - 为什么非平凡成员需要在同一类中为匿名 union 定义构造函数

c++ - 是否可以使用包含 {sub,super} 类函数指针的回调表?

clojure - 为什么 Clojure 的反向函数返回一个非惰性序列?