std::erase 和 std::remove 组合以删除特定元素不适用于特定示例

std::erase and std::remove combination to delete specific element doesn't work for specific example

本文关键字:std 元素 适用于 不适用 删除 erase remove 组合      更新时间:2023-10-16
#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。

这是怎么回事?

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

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

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

通过remove(a.begin(), a.end(), a[0]),指示a的第0个元素的地址的东西被传入。当remove()运行时,一旦处理了第 0 个元素,传入的引用所指向的值就会更改,从而导致意外结果。

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

int toberemoved = a[0];
a.erase(remove(a.begin(),a.end(),toberemoved),a.end());