STL list erase items [duplicate]
Possible Duplicate:
Can you remove elements from a std::list while iterating through it?
I want to erase items from the list while iterating over. I have done this before, but somehow this simple example fails me. thnx for the help in advance!
#include<iostream>
#include<list>
using namespace std;
void main()
{
list<int> x;
for ( int i =0;i<10; i++)
x.push_back(i);
for( list<int>::iterator k = x.begin(); k != x.end();k++)
cout<<*k<<" ";
cout<<endl;
for( list<int>::iterator k = x.begin(); k != x.end();k++)
{
if ((*k)%2)
{
x.erase(k);
}
}
cout<<endl;
getchar();
}
Just FWIW, what you're talking about can also be done with (for one example) std::list::remove_if
:
template <class T>
class odd {
bool operator()(T const &value) {
return value % 2 != 0;
}
};
// ...
x.remove_if(odd);
With C++ 0x and/or Boost lambda, you can do this without defining even
separately, which is quite convenient for trivial conditions like this. In theory you could also define this in place with a combination of std::bind1st, std::bind2nd, std::equal and std::modulus -- but (IMO) the result would be sufficiently difficult to decipher that it would be inadvisable.
Note that std::list::remove_if
(unlike std::remove_if
) actually erases the items you ask to have removed, whereas std::remove_if
normally needs to be combined with a call to erase
to actually erase the removed items.
erase
returns the element after the erased element: http://www.cplusplus.com/reference/stl/vector/erase/
So try something like this:
for( list<int>::iterator k = x.begin(); k != x.end();)
if( (*k)%2 )
k=x.erase(k);
else
++k;
Instead of writing yet another for(;;) loop to iterate over a STL container, the whole thing can usually be done quicker with STL algorithms and lambda expressions.
Your example code can be rewritten as:
list<int> x;
int i = 0;
generate_n(back_inserter(x), 10, [&i](){ return i++; });
copy(x.begin(), x.end(), ostream_iterator<int>(cout, " "));
cout << endl;
x.remove_if([](int n){ return n%2==0; });
Your iterator is invalid when you do so. Do
k = x.erase(k);
精彩评论