开发者

STL list erase items [duplicate]

开发者 https://www.devze.com 2023-01-18 16:57 出处:网络
This question already has answers here: 开发者_运维知识库 Closed 10 years ago. Possible Duplicate:
This question already has answers here: 开发者_运维知识库 Closed 10 years ago.

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);
0

精彩评论

暂无评论...
验证码 换一张
取 消