从std :: list中删除/删除

时间:2013-01-21 14:54:31

标签: c++

  

可能重复:
  How to filter items from a std::map?
  std::list::erase not working

我对std :: list中的删除,擦除有一些愚蠢的问题。

我有一个定义为:

的类
class CBase
{
public:
    CBase(int i): m(i)
    {};

    int m;
};

然后,我把它设置为:

list<CBase> ml;
CBase b1(1);
CBase b2(2);
CBase b3(3);
CBase b4(4);
ml.push_back(b1);
ml.push_back(b2);
ml.push_back(b3);
ml.push_back(b4);

我可以删除m == 2 by;

的项目
for (list<CBase>::iterator it=ml.begin(); it!=ml.end(); ++it)
{
    if (it->m == 2)
    {
        ml.erase(it--);
    }
}
    // show what we have now:
for (list<CBase>::iterator it=ml.begin(); it!=ml.end(); it++)
{
    cout << it->m;
}

但如果我这样做:

for (list<CBase>::iterator it=ml.begin(); it!=ml.end(); it++)
{
    if (it->m == 2)
    {
        ml.erase(it);
        it--;
    }
}

会有例外。这是为什么?

如果我想删除b3,

ml.remove(B3);

不会编译。我在网上找到的所有示例都使用list<int>,如果mylist.remove(3)调用mylist is list<int>则没有问题。我怎样才能使它发挥作用?

3 个答案:

答案 0 :(得分:2)

您正在取消引用指向已擦除元素的迭代器。使用erase()成员函数的返回值:

it = ml.erase(it);
// 'it' now points at first element after the last deleted element

答案 1 :(得分:1)

因为erase使迭代器无效。它可能不再被使用,包括减量运算符。

编辑:对于删除,它会删除值等于您指定的元素。 std::list使用operator==进行比较,除非您已定义,否则编译将失败。只需定义操作符即可。

答案 2 :(得分:1)

erase之后,传递给它的迭代器将无效。

现在,使用

ml.erase(it--);

您正在通过erase您的迭代器的副本向后移动您的副本,因此它不再引用列表中的相同位置 {<1}}在 --的副本准备好之后发生,但 erase之前的实际上已被调用。
调用之后,您的迭代器仍然有效,并且它是您删除的元素之前的一个位置。

但如果你这样做

erase

ml.erase(it); it--; 仍在尝试在调用后引用已删除的元素,并且当您尝试修改它时会出现异常,因为它无效。