Vector Erase Iterator

I have this code:

int main() { vector<int> res; res.push_back(1); vector<int>::iterator it = res.begin(); for( ; it != res.end(); it++) { it = res.erase(it); //if(it == res.end()) // return 0; } } 

"A random access iterator pointing to the new location of the element that follows the last element that was deleted when the function was called, that is, the end of the vector if the operation erased the last element in the sequence."

This code fails, but if I use the if(it == res.end()) and then return, it works. How are you coming? Does the for res.end() loop res.end() to prevent the inequality operator from working?

+64
c ++ iterator vector
Jan 10 2018-11-11T00:
source share
9 answers

res.erase(it) always returns the next valid iterator, if you delete the last element, it will point to .end()

At the end of the ++it loop, ++it always called, so you increment .end() , which is unacceptable.

Just checking for .end() still leaves an error, because you always skip the element at each iteration ( it gets "incremented" on return from .erase() , and then again on the loop)

You probably want something like:

  while (it != res.end()) { it = res.erase(it); } 

to erase every item

(for completeness: I assume this is a simplified example, if you just want every element to go away without performing an operation on it (like deleting), you should just call res.clear() )

When you only conditionally erase items, you probably want something like

 for ( ; it != res.end(); ) { if (condition) { it = res.erase(it); } else { ++it; } } 
+139
Jan 10 2018-11-11T00:
source share
 for( ; it != res.end();) { it = res.erase(it); } 

or, more general:

 for( ; it != res.end();) { if (smth) it = res.erase(it); else ++it; } 
+27
Jan 10 '11 at 10:27
source share

As a modification of the response to crazylammer, I often use:

 your_vector_type::iterator it; for( it = res.start(); it != res.end();) { your_vector_type::iterator curr = it++; if (something) res.erase(curr); } 

The advantage of this is that you donโ€™t have to worry about forgetting to increase your iterator, making it less error prone when you have complex logic. Inside the loop, curr will never be equal to res.end (), and it will be in the next element, regardless of whether you remove it from your vector.

+1
Aug 23 '17 at 16:47
source share

Because the erase in vector method returns the next iterator of the passed iterator.

I will give an example of deleting an element in a vector during iteration.

 void test_del_vector(){ std::vector<int> vecInt{0, 1, 2, 3, 4, 5}; //method 1 for(auto it = vecInt.begin();it != vecInt.end();){ if(*it % 2){// remove all the odds it = vecInt.erase(it); // note it will = next(it) after erase } else{ ++it; } } // output all the remaining elements for(auto const& it:vecInt)std::cout<<it; std::cout<<std::endl; // recreate vecInt, and use method 2 vecInt = {0, 1, 2, 3, 4, 5}; //method 2 for(auto it=std::begin(vecInt);it!=std::end(vecInt);){ if (*it % 2){ it = vecInt.erase(it); }else{ ++it; } } // output all the remaining elements for(auto const& it:vecInt)std::cout<<it; std::cout<<std::endl; // recreate vecInt, and use method 3 vecInt = {0, 1, 2, 3, 4, 5}; //method 3 vecInt.erase(std::remove_if(vecInt.begin(), vecInt.end(), [](const int a){return a % 2;}), vecInt.end()); // output all the remaining elements for(auto const& it:vecInt)std::cout<<it; std::cout<<std::endl; } 

print aw below:

 024 024 024 

More generation method:

 template<class Container, class F> void erase_where(Container& c, F&& f) { c.erase(std::remove_if(c.begin(), c.end(),std::forward<F>(f)), c.end()); } void test_del_vector(){ std::vector<int> vecInt{0, 1, 2, 3, 4, 5}; //method 4 auto is_odd = [](int x){return x % 2;}; erase_where(vecInt, is_odd); // output all the remaining elements for(auto const& it:vecInt)std::cout<<it; std::cout<<std::endl; } 
+1
Jul 29 '18 at 2:01
source share

Do not erase, then increase the iterator. There is no need to increase if your vector has a strange (or I donโ€™t even know) number of elements that you miss the end of the vector.

0
Jan 10 2018-11-11T00:
source share

The it ++ instruction is executed at the end of the block. Therefore, if you delete the last item, you are trying to increment an iterator that points to an empty collection.

0
Jan 10 '11 at 10:25
source share

You increment it beyond the end of the (empty) container in the loop loop expression of the loop.

0
Jan 10 2018-11-11T00:
source share

Also, the following seems to work:

 for (vector<int>::iterator it = res.begin(); it != res.end(); it++) { res.erase(it--); } 

Not sure if this is flawed?

0
Sep 07 '12 at 15:38
source share
 if(allPlayers.empty() == false) { for(int i = allPlayers.size() - 1; i >= 0; i--) { if(allPlayers.at(i).getpMoney() <= 0) allPlayers.erase(allPlayers.at(i)); } } 

This works for me. And do not think that the indices are already erased.

0
Apr 30 '14 at 8:49
source share



All Articles