List Iterator Remove()

Ste*_*eve 14 c++ stl list

我有一个列表迭代器,它通过一个列表并删除所有偶数.我可以使用list迭代器来打印出数字,但是我不能使用list的remove()并传入dereferenced迭代器.

我注意到当remove()语句生效时,*itr被破坏了吗?有人可以解释一下吗?

#include <iostream>
#include <list>

#define MAX 100

using namespace std;

int main()
{
    list<int> listA;
    list<int>::iterator itr;

    //create list of 0 to 100
    for(int i=0; i<=MAX; i++)
        listA.push_back(i);

    //remove even numbers
    for(itr = listA.begin(); itr != listA.end(); ++itr)
    {
        if ( *itr % 2 == 0 )
        {
            cout << *itr << endl;
            listA.remove(*itr);    //comment this line out and it will print properly
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

180*_*ION 44

上面的代码存在一些问题.首先,remove将使指向已删除元素的任何迭代器无效.然后继续使用迭代器.remove在一般情况下(虽然不在你的情况下)很难分辨哪些元素会被擦除,因为它可以删除多个元素.

其次,你可能使用了错误的方法.删除将迭代列表中的所有项目以查找任何匹配的元素 - 这在您的情况下效率低,因为只有一个.看起来你应该使用这个erase方法,你可能只想删除迭代器位置的项目.好处erase是它返回一个处于下一个有效位置的迭代器.使用它的惯用方法是这样的:

//remove even numbers
for(itr = listA.begin(); itr != listA.end();)
{
    if ( *itr % 2 == 0 )
    {
        cout << *itr << endl;
        itr=listA.erase(itr);
    }
    else
      ++itr;
}
Run Code Online (Sandbox Code Playgroud)

最后,您还可以使用remove_if与您正在执行的操作相同的操作:

bool even(int i) { return i % 2 == 0; }

listA.remove_if(even);
Run Code Online (Sandbox Code Playgroud)