Question

#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

Prints:

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

1, 0, 0, 0,

Why is this happening? Shouldn't only the first element of the vector be removed?

I suppose std::remove doesn't stop at the first element, but runs through the whole vector. Is there any way I can use the erase-remove idiom on collections with non-unique elements?

Was it helpful?

Solution

The third argument to std::remove is a const reference. You are changing the value of the element refered to as you move elements around, leading to undefined behaviour.

This would be well behaved:

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

Output:

1, 1, 1,

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top