шаблон класса с лямбдой - PullRequest
       12

шаблон класса с лямбдой

0 голосов
/ 13 октября 2019

Предположим, вы идете и что-то делаете с каждым элементом вектора или массива. Предположим также, что мы хотим подсчитать все элементы, которые «удовлетворяют» некоторому предикату.

Поскольку лямбда-выражение должно иметь состояние, мы можем сделать что-то вроде этого:

#include <cstdint>
#include <functional>

template<typename T, class F>
class CountAcummulator{
    size_t count = 0;

    F f;

public:
    constexpr CountAcummulator(F f) : f(std::move(f)){}

    constexpr void operator()(T const &a){
        if (std::invoke(f, a))
            ++count;
    }

    constexpr size_t get() const{
        return count;
    }
};

int main(){
    int x[] = { 1, 2, 3, 4, 5 };

    auto f = [](int a){
        return a > 3;
    };

    CountAcummulator<int, decltype(f)> ca{ f };

    for(auto i : x){
        // do something
        ca(i);
    }

    return ca.get();
}

Ссылка: https://gcc.godbolt.org/z/pjtcCG

К сожалению, я нашел это очень сложным в использовании. Если мы добавим проекцию (другую лямбду), этот класс станет непригодным для использования.

Есть ли способ улучшить этот класс, чтобы его можно было использовать?

1 Ответ

0 голосов
/ 14 октября 2019

Существует стандартный алгоритм std :: count_if , который считает все элементы, удовлетворяющие предикату. Это должен быть предпочтительный метод, если у вас нет веских причин не делать этого.

#include <algorithm>

int main(){
    int x[] = { 1, 2, 3, 4, 5 };

    auto f = [](int a){
        return a > 3;
    };

    return std::count_if(std::begin(x), std::end(x), f);
}
...