我在迭代时可以从std :: list中删除元素吗?例如:
std::list<int> lst;
//....
for (std::list<int> itr = lst.begin(); itr != lst.end(); itr++)
{
if (*itr > 10)
lst.remove(*itr);
}
Run Code Online (Sandbox Code Playgroud)
?为什么?
Vla*_*lad 33
正确的代码如下:
for (std::list<int>::iterator itr = lst.begin(); itr != lst.end(); /*nothing*/)
{
if (*itr > 10)
itr = lst.erase(itr);
else
++itr;
}
Run Code Online (Sandbox Code Playgroud)
从列表中删除项时,可能会使迭代器无效(如果它指向要删除的项.)因此,您需要删除using erase(返回指向下一项的有效迭代器).
更好的想法是使用std::remove_if:
bool greater_than_10(int x)
{
return x > 10;
}
lst.remove_if(greater_than_10);
Run Code Online (Sandbox Code Playgroud)
如果你的编译器支持lambdas,你可以把它缩短:
lst.remove_if([](int x){ return x > 10; });
Run Code Online (Sandbox Code Playgroud)
(我没有测试这段代码,因为我的编译器不是那么新;感谢lambda函数从@John Dibling的答案中偷走了.)
实际上,从列表中删除仅使指向要删除的项的迭代器无效.但请注意,其他STL容器没有此属性.
因此,简而言之:一般来说,在迭代它时不应该从列表中删除项目,因为删除可能使迭代器无效(并且程序可能会崩溃).但是,如果您完全确定删除的项不是删除时使用的任何迭代器引用的值,则可以删除.
请注意,对于其他STL容器(例如向量),约束甚至更严格:从容器中删除不仅使指向已删除项的迭代器失效,而且可能使其他迭代器失效!因此,在迭代它们时从这些容器中删除更有问题.
否.示例代码无效itr,导致未定义的行为.但这会奏效:
for (std::list<int>::iterator itr = lst.begin(); itr != lst.end(); )
{
if (*itr > 10)
itr = lst.erase(itr);
else
++itr;
}
Run Code Online (Sandbox Code Playgroud)