可能重复:
Can you remove elements from a std::list while iterating through it?
我希望在迭代时从列表中删除项目。我以前做过这个,但不知怎的,这个简单的例子让我失望了。 thnx提前帮助!
#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();
}
答案 0 :(得分:8)
只是FWIW,您所谈论的内容也可以用(例如)std::list::remove_if
完成:
template <class T>
class odd {
bool operator()(T const &value) {
return value % 2 != 0;
}
};
// ...
x.remove_if(odd);
使用C ++ 0x和/或Boost lambda,您可以在不单独定义even
的情况下执行此操作,这对于像这样的琐碎条件非常方便。理论上你也可以用std :: bind1st,std :: bind2nd,std :: equal和std :: modulus的组合来定义它,但是(IMO)结果将很难破译它会是不可取的。
请注意,std::list::remove_if
(与std::remove_if
不同)实际上会删除您要求删除的项目,而std::remove_if
通常需要与对erase
的调用相结合才能实际删除删除已删除的项目。
答案 1 :(得分:5)
erase
返回已删除元素后的元素:http://www.cplusplus.com/reference/stl/vector/erase/
所以尝试这样的事情:
for( list<int>::iterator k = x.begin(); k != x.end();)
if( (*k)%2 )
k=x.erase(k);
else
++k;
答案 2 :(得分:3)
不是为(;;)循环编写另一个循环来迭代STL容器,而是使用STL算法和lambda表达式来完成整个过程。
您的示例代码可以重写为:
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; });
答案 3 :(得分:0)
执行此操作时,您的迭代器无效。做
k = x.erase(k);