2

我应该实现一个从容器中删除一系列值的函数。所以

eraseRange(v, 1.5, 24);

例如,将从容器 v 中删除任何大于 1.5 且小于 24 的值。我的函数非常适用于列表,我在其中使用:

container.erase(remove_if(container.begin(), container.end(), rg));

其中 rg 检查它是否在范围内(该部分的实现不是问题,所以我不打算详细说明)。

但是,当为向量调用 eraseRange 并使用类似的方法来擦除值时,只会擦除第一个值。因此,如果我有一个数字从 1 到 10 的向量,我会调用:

eraseRange(v, 3, 7);

只有3个被删除。

现在这通常不会成为问题,我只需使用迭代器来检查值。除了这个特定的练习,for/while/do 循环是明确禁止的……

所以问题似乎出在具有随机访问迭代器的容器上。而且我不确定要实施什么作为替代方案。帮助?

4

2 回答 2

11

有几个重载erase

一个重载,即您正在使用的重载,采用单个迭代器并擦除迭代器指向的元素。

您应该使用的另一个重载采用一个范围(一对迭代器)并擦除该范围内的所有元素:

c.erase(remove_if(c.begin(), c.end(), rg), c.end());
                                         ^^^^^^^^^

[我不确定为什么你的代码“非常适合列表”,就像你说的那样;std::list具有相同的两个重载erase. 请注意,它std::list还有一个成员函数 ,remove_if它提供了一个更好的擦除/删除算法的专门优化实现std::list(因为std::list它是作为链表实现的,它可以在不实际移动任何对象的情况下实现擦除/删除)。]

于 2011-10-11T17:36:28.927 回答
2

remove_if returns a single iterator to "new last". That is its shuffled everything satisfying your predicate to past new last in the vector. Everything before new last doesn't satisfy your predicate, while everything past it does. Since you're executing the erase for only a single item from the vector, you're only removing the new last -- that is only one thing that satisfied your predicate. Instead you want to erase everything from new last -> end which is everything that satisfied your predicate

container.erase(
   remove_if(container.begin(), container.end(), rg), 
   container.end()
 );
于 2011-10-11T17:38:28.647 回答