在非唯一集合上使用erase-remove惯用法

时间:2014-01-12 11:24:56

标签: c++ c++11 stl-algorithm erase-remove-idiom

#include <iostream>
#include <vector>
#include <algorithm>

int main()
{
    enum class En{A, B};
    std::vector<En> vec{En::A, En::B, En::A, En::B, En::A, En::B, En::A};

    for(const auto& i : vec) std::cout << int(i) << ", ";
    std::cout << std::endl;

    vec.erase(std::remove(std::begin(vec), std::end(vec), vec.front()), 
              std::end(vec));

    for(const auto& i : vec) std::cout << int(i) << ", ";
    std::cout << std::endl;

    return 0;
}

Ideone http://ideone.com/NTPVyE

  

打印

     

0,1,0,1,0,1,0,

     

1,0,0,0,

为什么会这样?不应该只删除矢量的第一个元素吗?

我认为std::remove不会停留在第一个元素,而是遍历整个向量。有没有办法可以在具有非唯一元素的集合上使用 erase-remove idiom

1 个答案:

答案 0 :(得分:7)

std::remove的第三个参数是const引用。在移动元素时,您正在更改所引用元素的值,从而导致未定义的行为。

这表现得很好:

auto elem = vec.front(); // copy front element
vec.erase(std::remove(std::begin(vec), std::end(vec), elem), 
          std::end(vec));

输出:

  

1,1,1,