21
#include <vector>
#include <algorithm>

using namespace std;

int main() {
    vector<int> a = {1,2,3,7,1,5,4};
    vector<int> b = {6,7,4,3,3,1,7};
    a.erase(remove(a.begin(),a.end(),a[0]),a.end());
    b.erase(remove(b.begin(),b.end(),b[0]),b.end());

    return 1;
}

对于这个特定的例子,我的 GNU gdb Ubuntu 7.7.1 声明在返回 1 行: a = {2,3,7,1,5,4} 不是预期的(只删除一个 1),并且 b = {7 ,4,3,3,1} 这不是预期的。

我的期望是 b 应该是 a=2,3,7,5,4 和 b=7,4,3,3,1,7。

这里发生了什么事?

4

1 回答 1

20

的声明std::remove()看起来像

template <class ForwardIterator, class T>
  ForwardIterator remove (ForwardIterator first, ForwardIterator last, const T& val);

请注意,最后一个参数是一个引用。因此在编译后它有效地传递了指定元素的地址。

By ,传入的是remove(a.begin(), a.end(), a[0])指向第 0 个元素的地址的东西。运行时,一旦处理了第 0 个元素,传入的引用所指向的值就发生了变化,从而导致了意想不到的结果。aremove()

要获得预期的结果,请在调用之前进行复制std::remove()

int toberemoved = a[0];
a.erase(remove(a.begin(),a.end(),toberemoved),a.end());
于 2015-02-25T15:02:55.407 回答