c++ - 在迭代 std::list 时删除

标签 c++ list

如果我在 for 循环中使用 iterator 并且在迭代器的当前迭代中使用 erase,则 for 循环应该继续正常并访问其余的 list 元素?

根据我的阅读,这应该是这种情况,并且是 listdequevector 的主要区别特征。就我而言,queue 可能有效,但我需要这种行为。

这是我正在考虑的循环:

    std::list<Sequence>::iterator iterator;
    iterator=m_concurrents.begin();
    for (;iterator!=m_concurrents.end();++iterator){
        if (iterator->passes()){
            m_concurrents.erase(iterator);
        }
    }

最佳答案

编写该循环的惯用方法是:

for (auto i = list.begin(); i != list.end();) {
    if (condition)
        i = list.erase(i);
    else
        ++i;
}

您可以对 setmultisetmapmultimap 执行相同的操作。对于这些容器,您可以删除一个元素而不影响任何迭代器对其他元素的有效性。其他容器,如 vectordeque 就不是那么友好了。对于那些容器,只有被删除的迭代器之前的元素保持不变。这种差异仅仅是因为 list 将元素存储在单独分配的节点中。很容易取出一个链接。 vector 是连续的,取出一个元素会将其后的所有元素移回一个位置。

您的循环中断是因为您在某些给定条件下删除了 i 处的元素。 i 在该调用之后不再是有效的迭代器。您的 for 循环然后递增 i,但 i 无效。人间 hell 随之而来。这就是为什么 erase 将迭代器返回到被删除后的元素的确切情况...这样您就可以继续遍历 list

你也可以使用 list::remove_if :

list.remove_if([](auto& i) { return i > 10; });

在 lambda 中,如果应该删除该元素,则返回 true。在此示例中,它将删除所有大于 10 的元素。

关于c++ - 在迭代 std::list 时删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40327383/

相关文章:

c++ - 在最后一次出现字符后优雅地删除字符串的一部分

c++ - 从函数访问类

c++ - 有没有办法将 C++ 库包含到 XUL 桌面应用程序中?

java - 如何在 Java 中创建与旧列表相同类型的新列表?

python - 在嵌套列表python中连接项目

python 多个列表中的最小范围

string - Lisp - 显示要列出的字符串

c++ - 两次使用cin的问题

python - 如何检查一个列表/字典的元素是否存在于python中的另一个列表/字典中

c++ - 使用 QPixmap::load( ) 读取 GeoTiff 时的 TIFFReadDirectory 警告