C++ 列表擦除不兼容迭代器

C++ 列表擦除不兼容迭代器,c++,stl,C++,Stl,我有一个对象列表。我从列表中获取一些项目,并对这些项目进行处理。如果工作没有错误,我希望从列表中删除这些项目。之后,在擦除时,我得到了不兼容迭代器的异常。我知道tmp是不同的列表。但如何解决这个问题呢 #include <list> class A { public: A(int i):i_(i){} private: int i_; }; int _tmain(int argc, _TCHAR* argv[]) { std::list<A>

我有一个对象列表。我从列表中获取一些项目,并对这些项目进行处理。如果工作没有错误,我希望从列表中删除这些项目。之后,在擦除时,我得到了不兼容迭代器的异常。我知道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;
}
#包括
甲级
{
公众:
A(inti):i_ui(i){}
私人:
国际组织;
};
int _tmain(int argc,_TCHAR*argv[]
{
std::列表;
A(1),b(2),c(3);;
列表。推回(a);
列表。推回(b);
列表。推回(c);
std::列出tmp;
insert(tmp.end(),list.begin(),list.end());
//用tmp做点什么
//如果一切正常,则删除已完成的操作
擦除(tmp.begin(),tmp.end());
返回0;
}

tmp.Insert
并不总是获取完整的
列表
。它可以复制
列表
的一部分,所以我不想清除整个
列表

我想你应该清除你的列表,使用,list.clear() 此外,在代码中:

list.erase(tmp.begin(), tmp.end());
这是错误的!我想你的意思是:

list.erase(list.begin(), list.end());
打字错误

我想你想输入:

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

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

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

在程序中,
std::list
析构函数将导致列表被清除,因此您甚至不需要执行显式清除

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

 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());
 }
class-ciscontainedotherlist
{ 
私人:
常数标准::列表和m_列表;
公众:
ciscontainedotherlist(const std::list&list);
//如果val在m_列表中,则返回true
布尔运算符()(常量int&val)常量
{
std::list::const_迭代器iter
=std::find(m_list.begin(),m_list.end(),val);
return(iter!=m_list.end())
}
}
int main()
{
...
CIS包含在其他列表ifInOtherList(tmp)中;
标准::列表::迭代器iter=
删除_if(list.begin()、list.end()、ifNotherList);
//删除与谓词匹配的所有内容
擦除(iter,list.end());
}

您正试图使用
tmp
的迭代器从
列表中删除-这毫无意义,会删除什么

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

或者,只需
list.clear()

我对使用boost::iterator\u范围有了想法。其保存范围供以后删除。可以吗

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());
typedef std::list::iterator AIter;
std::列出tmp;
迭代器的范围(list.begin(),list.end());
insert(tmp.end(),range.begin(),range.end());
list.erase(range.begin(),range.end());

听起来您的问题与中的问题类似。您可能会使用类似的解决方案

这个注释很有道理,但是为什么这段代码在g++4.5下编译并运行良好?@Semen:因为编译器只检查迭代器是否具有正确的操作类型,而迭代器确实是这样做的。是的,它应该编译,并且确实编译。但是为什么它运行时没有引发任何异常或类似的情况呢?@Semen,部分原因是库强制执行不同数量的检查。性病只是说它会导致“未定义的行为”,以此来逃避类似的事情。但这并不是一种逃避,像微软这样的库允许你打开非常严格的STL检查,但是性能的影响是可怕的。请看这里:记住列表迭代器的范围如何。将范围复制到tmp。若一切正常,从列表中删除成员范围?不。我不想清除整个列表。因为tmp可以包含
列表的一部分
。我不希望清除tmp。如果所有操作都在
tmp
上完成,我需要清除
list
,tmp是我可以操作的列表的子集。但只清除
tmp
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());