I'm trying to write an in-place filter function that works similarly to Python's filter. For example:
std::vector<int> x = {1, 2, 3, 4, 5};
filter_ip(x, [](const int& i) { return i >= 3; });
// x is now {3, 4, 5}
First I tried this:
template <typename Container, typename Filter>
void filter_ip(Container& c, Filter&& f)
{
c.erase(std::remove_if(c.begin(), c.end(), std::not1(f)), c.end());
}
However, that doesn't work because lambdas don't have an argument_type
field.
This following variant does work:
template <typename Container, typename Filter>
void filter_ip(Container& c, Filter&& f)
{
c.erase(std::remove_if(c.begin(), c.end(),
[&f](const typename Container::value_type& x) {
return !f(x);
}),
c.end());
}
However, it seems less than ideal because before, it would only have required that Container
have begin
, end
, and erase
, while now it also requires that it defines a value_type
. Plus it looks a little unwieldy.
This is the 2nd approach in this answer. The first would use std::not1(std::function<bool(const typename Container::value_type&)>(f))
instead of the lambda, which still requires the type.
Is there any way around this? Intuitively it seems it should be really simple since all you need to do is apply a not to a bool which you already know f
returns.
Aucun commentaire:
Enregistrer un commentaire