1

Let's say that I have vector of pairs, where each pair corresponds to indexes (row and column) of certain matrix I am working on

using namespace std;
vector<pair<int, int>> vec;

I wanted to, using auto, go through the whole vector and delete at once all the pairs that fulfill certain conditions, for example something like

for (auto& x : vec) {
    if (x.first == x.second) {
        vec.erase(x); 
    }
}

but it doesn't work, as I suppose vec.erase() should have an iterator as an argument and x is actually a pair that is an element of vector vec, not iterator. I tried to modify it in few ways, but I am not sure how going through container elements with auto exactly works and how can I fix this.

Can I easily modify the code above to make it work and to erase multiple elements of vector, while going through it with auto? Or I should modify my approach?

For now it's just a vector of pairs, but it will be much worse later on, so I would like to use auto for simplicity.

Kusavil
  • 294
  • 6
  • 15
  • 1
    Confirming your supposition: [Removing item from vector, while in C++11 range 'for' loop?](https://stackoverflow.com/questions/10360461/removing-item-from-vector-while-in-c11-range-for-loop) – WhozCraig Jan 24 '20 at 01:35

2 Answers2

5

vector::erase() invalidates any outstanding iterators, including the one your range based for loop is using. Use std::remove_if():

vec.erase(
    std::remove_if(
        vec.begin(),
        vec.end(),
        [](const pair<int,int> &xx) { return xx.first == xx.second; }
    ), vec.end()
);

std::remove_if() swaps the elements to the end of the vector and then you can safely erase them.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
gct
  • 14,100
  • 15
  • 68
  • 107
0

I would prefer something like this:

  pair<int, int> pair = nullptr;
  auto iter = vec.begin();
    while(iter != vec.end()){
        pair = (*iter);
        if(pair.first == pair.second){
            iter = this->vec.erase(iter);
        }else{
            ++iter;
        }
    }
TBockmair
  • 83
  • 6