繁体   English   中英

std::list 擦除不兼容的迭代器

[英]std::list erase incompatible iterator

我有对象列表。 我从该列表中获取一些项目并对项目做一些事情。 如果工作完成没有错误,我希望从列表中删除这些项目。 之后,在擦除时,我得到了不兼容迭代器的异常。 我知道 tmp 是不同的列表。 但是如何解决这个问题呢?

#include <list>

class A
{
public:
    A(int i):i_(i){}
private:
    int i_;
};

int _tmain(int argc, _TCHAR* argv[])
{
    std::list<A> list;
    A a(1), b(2), c(3);
    list.push_back(a);
    list.push_back(b);
    list.push_back(c);

    std::list<A> tmp;
    tmp.insert(tmp.end(), list.begin(), list.end());
    // do something with tmp
    // if all is ok, then erase what is done
    list.erase(tmp.begin(), tmp.end());

    return 0;
}

tmp.Insert并不总是得到完整的list 它可以复制list的一部分,所以我不想清除整个list

您不能使用另一个列表中的迭代器从一个列表中擦除。 迭代器“指向”列表中的某个节点。 它指向特定列表中的某些内容 当您将这些内容复制到另一个列表中时,您现在有两个带有两组节点的列表。 您的迭代器仅指向其中一个副本,而不是两者。

在程序中, std::list析构函数会导致你的列表被清理,所以你甚至不需要做一个明确的清除。

正如其他人所说,您可以使用clear吹走列表的内容。 但我不是 100% 确定这就是你的意思。 您的意思是删除列表中所有也在 tmp 中的内容吗? 如果是这种情况,那么您可能希望将remove_if与谓词一起使用

 class CIsContainedInOtherList
 { 
 private:
     const std::list<int>& m_list;
 public:
      CIsContainedInOtherList(const std::list<int>& list);

      // return true if val is in m_list
      bool operator()(const int& val) const
      {
          std::list<int>::const_iterator iter 
             = std::find(m_list.begin(), m_list.end(), val);
          return (iter != m_list.end())
      }
 }

 int main()
 {
      ...
      CIsContainedInOtherList ifInOtherList(tmp);
      std::list<int>::iterator iter = 
              remove_if(list.begin(), list.end(), ifInOtherList);
      // remove everything that matched the predicate
      list.erase(iter, list.end());
 }

我认为您想清除列表,使用 list.clear() 另外,在您的代码中:

list.erase(tmp.begin(), tmp.end());

错了:我认为你的意思是:

list.erase(list.begin(), list.end());
  list.erase(tmp.begin(), tmp.end());
//^^^^

错字!

我想你想输入:

  tmp.erase(tmp.begin(), tmp.end());
//^^^^

出现错误的原因是,您无法使用从另一个列表获得的迭代器范围从一个列表中删除元素。 从一个列表获得的迭代器无法从另一个列表获得的迭代器中访问。

您正在尝试使用tmp的迭代器从list中删除 - 这没有任何意义,什么会被删除?

 list.erase(list.begin(), list.end());

或者,只是list.clear();

我有使用 boost::iterator_range 的想法。 其保存范围以供以后删除。 可以吗?

typedef std::list<A>::iterator AIter;

std::list<A> tmp;
boost::iterator_range<AIter>  range(list.begin(), list.end());
tmp.insert(tmp.end(), range.begin(), range.end());

list.erase(range.begin(), range.end());

听起来您的问题类似于Can you remove elements from a std::list while iterate through it? . 您可能可以使用类似的解决方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM