说我们得到了:
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_end
到V.end()
的元素不我们正在删除的偶数整数。例如,如果v
以1 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
的情况下解决这个问题?
答案 0 :(得分:7)
听起来你想使用partition()
将矢量划分为起始处的奇数值组和结尾处的偶数值。 partition()
将向第二个分组的第一个元素返回一个迭代器。
至于WTF,我不确定为什么你会期望删除操作来保存你想要删除的元素,方法是将它们(这是额外的工作)复制到容器的末尾。
大多数人认为remove()
(以及它的表兄弟)中的WTF是这样的事实:向量的大小没有减少,你必须在删除操作之后调用erase()
来实际删除不需要的元素。 / p>
答案 1 :(得分:2)
我想重点是函数被调用remove_if
是有原因的。它删除元素。它不会移动它们或选择它们。在调用remove_if之后,不再保证您删除的元素存在。我们保证,first
和new_last
之间的元素不包含任何已移除的元素。
std::partition
会是更好的选择,不是吗?或者也许remove_copy_if
,具体取决于您要做的事情。
答案 2 :(得分:2)
如果您真的想使用“已删除”元素,则需要std::partition。