Предположим, вы идете и что-то делаете с каждым элементом вектора или массива. Предположим также, что мы хотим подсчитать все элементы, которые «удовлетворяют» некоторому предикату.
Поскольку лямбда-выражение должно иметь состояние, мы можем сделать что-то вроде этого:
#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
К сожалению, я нашел это очень сложным в использовании. Если мы добавим проекцию (другую лямбду), этот класс станет непригодным для использования.
Есть ли способ улучшить этот класс, чтобы его можно было использовать?