Say we’ve got:
struct IsEven { bool operator() (int i) { return i % 2 == 0; } };
Then:
vector<int> V; // fill with ints vector<int>::iterator new_end = remove_if(V.begin(), V.end(), IsEven()); V.erase(new_end, V.end());
works fine (it leaves V with only the odd integers). But it seems that the elements from new_end to V.end() are not the even integers that we’re deleting. For example, if v starts out as 1 4 2 8 5 7, then I’m getting 8 5 7 for those elements (although after the erase call, the vector indeed has 1 5 7 left).
Apparently, (according to http://www.sgi.com/tech/stl/remove_if.html)
The iterators in the range [new_last, last) are all still dereferenceable, but the elements that they point to are unspecified.
First of all, WTF? And second, how do I get around this without essentially reimplementing remove_if?
It sounds like you want to use
partition()to partition the vector into groups of odd values at the start and even values at the end.partition()will return an iterator to the first element of the second grouping.As for the WTF, I’m not sure why you would expect a remove operation to preserve the elements you want to remove by copying them (that’s extra work) to the end of the container. Most people consider the WTF in
remove()(and it’s cousins) to be the fact that the size of the vector is not reduced and you have to callerase()to actually delete undesired elements after the remove operation.