и две функции предиката в C ++ - PullRequest
0 голосов
/ 23 мая 2018

Я ищу способ создания двоичной операции между двумя предикатными функциями.Это мое объявление предикатной функции:

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 ++?

Ответы [ 2 ]

0 голосов
/ 23 мая 2018

Конечно, просто используйте лямбду:

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

Это позволяет избежать дополнительных издержек на стирание типов std::function, принимая фактические типы, необходимые для исходных предикатов, и возвращая лямбду напрямую.Затем вы можете сохранить это в std::function, если вам нужно, или просто позволить компилятору определить тип с помощью auto.

0 голосов
/ 23 мая 2018

Это должно сработать:

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 ) };
}

не понятно, почему вы хотите сделать его статичным.

...