【问题标题】:Combining predicates in a functional way以函数方式组合谓词
【发布时间】:2021-01-23 07:36:54
【问题描述】:

Boost Hana 是否提供了一种将谓词与逻辑运算符结合起来的方法?

我指的是大致这样的东西

constexpr auto both = [](auto&& f, auto&& g){
    return [&f,&g](auto&& x){ return f(x) && g(x); };
};

可以这样使用:

int main() {
    std::vector<int> v{1,2,3,4,5,6,7,8,9,10};
    auto less_than_7 = hana::reverse_partial(std::less_equal<int>{}, 7);
    auto more_than_3 = hana::reverse_partial(std::greater_equal<int>{}, 3);
    auto r = ranges::views::remove_if(v, both(less_than_7, more_than_3));
}

在哪里,来自 Hana,我希望还有一种以类似于 hana::on 的中缀方式使用它的方法,如 both(less_than_7, more_than_3) === less_than_7 ^both^ more_than_3(尽管 and 会更好,但我刚刚发现它是&amp;&amp; 的同义词。

或者它是否提供了一种方法来提升标准运算符 &amp;&amp; 以对函数函子进行操作?

【问题讨论】:

    标签: c++ functional-programming functor boost-hana lifting


    【解决方案1】:

    你可以使用demux 喜欢:

    auto both = hana::demux(std::logical_and<bool>{});
    // Or for any number of predicates
    auto all = hana::demux([](auto const&... x) noexcept(noexcept((static_cast<bool>(x), ...))) { return (true && ... && static_cast<bool>(x)); });
    ranges::views::remove_if(v, both(less_than_7, more_than_3));
    

    【讨论】:

    • 哦,太好了! all 这个名字有点误导,因为它传达了恕我直言,它将and/&amp;&amp;零个或多个 谓词的结果组合在一起,而不是两个。我会将该名称保留给hana::demux([](auto const&amp;... x){ return (... &amp;&amp; x); })。如果你觉得很好,我可以自己编辑你的答案,如果没有,我可以为读者添加另一个答案(你的仍然被接受)。
    • @Enrico 出于某种原因,我认为logical_and 是可变的。不过现在修复了
    • 哦,那是什么?你能解释一下为什么noexcept(bla)(我猜这与函数的作用无关)和true &amp;&amp; ... &amp;&amp;,我怀疑这与使用零参数调用函数all有关,这似乎没有无论如何工作。
    • @Enrico noexcept(...) 只是使 lambda noexcept 如果所有参数都可以noexcept 转换为布尔值(允许进行一些优化)。 true &amp;&amp; ... &amp;&amp; 是多余的,但我发现它更清楚(... &amp;&amp; 有一个边缘情况,将其变为 true 用于空包)。和all()(x) == true(因为“所有 0 个约束都满足”而有意义)
    猜你喜欢
    • 2010-10-07
    • 2021-05-13
    • 1970-01-01
    • 2018-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多