I have a std::list of objects. The list is sorted and must stay that way. I need to find those objects that satisfy a certain criterion (I have a predicate for this), pass them to a function, and then delete the objects from the list.
It's not too hard to write a loop that calls std::find_if()
, invokes the operation on its result (if any), calls list.erase()
, and passes the result of that as begin iterator to the next call to std::find_if()
. IME, however, people find such code harder to read than it is to write it.
So I would preferably employ some algorithm(s) from the std lib rather than writing my own loop.
One idea was to (ab)use std::list<>::remove_if()
: Invoke the operation on the elements that match _from the predicate, before it returns true
, so that the list will delete the elements. Would that be standard-conforming? (The items themselves won't be changed, only data they refer to.)
Or can you come up with a better solution? (Again, the main objective is to make this easy to read and understand.) Maybe it's because I just ran into it, but to me it seems this might not be an uncommon usage pattern for a sequence of objects.
Note: For the time being , we're firmly stuck in C++03 land. :-/
C++11/14/17 solutions would be interesting and thus welcome, but I do need something that works with C++03.
Yes. There's nothing in the standard specification that requires the predicate to be a pure function. So this C++11 solution would be perfectly fine:
Nothing even requires the predicate to ever return
true
. You can even useremove_if
as a poor man's, unnecessarily confusingfor_each
:That's pointless and inefficient, but it's definitely standards conforming.
You can write the equivalent in C++03 as a function object. Whether or not you find that easier to read than the for loop is a matter of opinion. But it's not wrong.