【问题标题】:and two predicate functions in c++和 C++ 中的两个谓词函数
【发布时间】:2018-11-02 19:45:54
【问题描述】:

我正在寻找一种在两个谓词函数之间创建二元运算的方法。这是我的谓词函数声明:

template <typename T>
using Predicate = std::function<bool(T const&)>;

我正在寻找一种将两个谓词函数“合并”为一个的方法:

template <typename T>
static Predicate<T> andPredicate(Predicate<T> a, Predicate<T> b) {
   // ???
}

预期行为:

Predicate<int> a = [](int a) { return a < 5; };
Predicate<int> b = [](int a) { return a > 0; };

Predicate<int> c = andPredicate(a, b); // a < 5 && a > 0

int number = 3;
bool result = c(number);

这样的事情在 C++ 中是否可行?

【问题讨论】:

  • 为什么是静态的?
  • 您需要返回一个 functionoid,当被调用时,它本身会使用自己的参数调用 ab(它之前已存储)并返回其结果的 and。你不远;)

标签: c++ functional-programming predicate


【解决方案1】:

当然,只需使用 lambda:

template <typename T>
Predicate<T> andPredicate(Predicate<T> a, Predicate<T> b) {
    return [=](T i) { return a(i) && b(i); };
}

您甚至可以通过利用模板来避免 std::function 的额外开销:

template <typename P1, typename P2>
auto andPredicate(P1&& a, P2&& b) {
    return [a = std::forward<P1>(a), b = std::forward<P2>(b)](const auto& i) {
        return a(i) && b(i);
    };
}

Live Demo

这通过接受原始谓词所需的实际类型并直接返回 lambda,避免了 std::function 的额外类型擦除开销。然后,如果需要,您可以将其存储在 std::function 中,或者让编译器使用 auto 推断类型。

【讨论】:

  • @Slava 哎呀,是的,已修复。
  • 非常感谢,正是我想要的。
  • 使用predicateCombinerstd::logical_and创建predicateCombiner和创建andPredicate会很有趣
  • @Slava 当然,you could do that,但我不认为在这种情况下它真的很值得。
【解决方案2】:

这应该可行:

template <typename T>
static Predicate<T> andPredicate(Predicate<T> a, Predicate<T> b) {
   return [a,b]( T const &val ) { return a( val ) and b( val ) };
}

目前尚不清楚为什么要将其设为静态。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-24
    • 1970-01-01
    • 1970-01-01
    • 2021-12-29
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    相关资源
    最近更新 更多