如何在std :: remove_if之后使用“removed”元素

时间:2009-01-25 07:37:01

标签: c++ stl

说我们得到了:

struct IsEven {
   bool operator() (int i) { return i % 2 == 0; }
};

然后:

vector<int> V; // fill with ints
vector<int>::iterator new_end = remove_if(V.begin(), V.end(), IsEven());
V.erase(new_end, V.end());

工作正常(只留下奇数整数V)。但似乎从new_endV.end()的元素我们正在删除的偶数整数。例如,如果v1 4 2 8 5 7开头,那么我将获得8 5 7这些元素(尽管在erase调用之后,该向量确实有1 5 7左)。

显然,(根据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.

首先,WTF?第二,如何在不重新实现remove_if的情况下解决这个问题?

3 个答案:

答案 0 :(得分:7)

听起来你想使用partition()将矢量划分为起始处的奇数值组和结尾处的偶数值。 partition()将向第二个分组的第一个元素返回一个迭代器。

至于WTF,我不确定为什么你会期望删除操作来保存你想要删除的元素,方法是将它们(这是额外的工作)复制到容器的末尾。 大多数人认为remove()(以及它的表兄弟)中的WTF是这样的事实:向量的大小没有减少,你必须在删除操作之后调用erase()来实际删除不需要的元素。 / p>

答案 1 :(得分:2)

我想重点是函数被调用remove_if是有原因的。它删除元素。它不会移动它们或选择它们。在调用remove_if之后,不再保证您删除的元素存在。我们保证,firstnew_last之间的元素不包含任何已移除的元素。

std::partition会是更好的选择,不是吗?或者也许remove_copy_if,具体取决于您要做的事情。

答案 2 :(得分:2)

如果您真的想使用“已删除”元素,则需要std::partition