I have code to remove all elements from a std::vector<int>
that are less than some int limit
. I've written some functions that partially apply lambdas:
auto less_than_limit = [](int limit) {
return [=](int elem) {
return limit > elem;
};
};
auto less_than_three = less_than_limit(3);
When I test it with std::vector<int> v{1,2,3,4,5};
, I get the expected results:
for(auto e: v) {
std::cout << less_than_three(e) << " ";
}
// 1 1 0 0 0
I can easily remove all the elements less than three:
auto remove_less_than_three = std::remove_if(std::begin(v), std::end(v), less_than_three);
v.erase(remove_less_than_three, v.end());
for(auto e: v) {
std::cout << e << " ";
}
// 3 4 5
How would I remove elements greater than or equal to 3 using less_than_three
?
I tried wrapping less_than_three
in std::not1
, but got errors:
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/bits/stl_function.h:742:11: error: no type named 'argument_type' in 'struct main()::<lambda(int)>::<lambda(int)>'
class unary_negate
^
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/bits/stl_function.h:755:7: error: no type named 'argument_type' in 'struct main()::<lambda(int)>::<lambda(int)>'
operator()(const typename _Predicate::argument_type& __x) const
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/bits/predefined_ops.h:234:30: error: no match for call to '(std::unary_negate<main()::<lambda(int)>::<lambda(int)> >) (int&)'
{ return bool(_M_pred(*__it)); }
^
I then tried std::not1(std::ref(less_than_three))
, but got these errors:
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/bits/stl_function.h:742:11: error: no type named 'argument_type' in 'class std::reference_wrapper<main()::<lambda(int)>::<lambda(int)> >'
class unary_negate
^
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/bits/stl_function.h:755:7: error: no type named 'argument_type' in 'class std::reference_wrapper<main()::<lambda(int)>::<lambda(int)> >'
operator()(const typename _Predicate::argument_type& __x) const
^
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/bits/predefined_ops.h:234:30: error: no match for call to '(std::unary_negate<std::reference_wrapper<main()::<lambda(int)>::<lambda(int)> > >) (int&)'
{ return bool(_M_pred(*__it)); }
^
How can I negate the function in std::remove_if
without changing the logic of my lambdas? In other words, how can I emulate remove_unless
?
less_then_three
explicit.std::function<bool(int)> less_than_three = less_than_limit(3);
– Disclosureargument_type
, which is something thatnot1
requires. – Knobstd::experimental::not_fn
, which isn't that hard to implement (especially if you don't care about member pointers). – Olearyremove_if_not
function. – Kulturkampfremove_if
and modifying it, e.g. the one at en.cppreference.com/w/cpp/algorithm/remove withp(*i)
instead of!p(*i)
andfind_if
replaced byfind_if_not
. You'd no longer need a negative predicate and client code would presumably become a bit more readable. – Kulturkampf