c++ - 如果在从头到尾迭代时在 map 元素上调用 erase() 会发生什么?

标签 c++ stl iterator

在下面的代码中,我循环遍历 map 并测试是否需要删除元素。删除元素并继续迭代是否安全,或者我是否需要在另一个容器中收集 key 并执行第二个循环来调用 erase()?

map<string, SerialdMsg::SerialFunction_t>::iterator pm_it;
for (pm_it = port_map.begin(); pm_it != port_map.end(); pm_it++)
{
    if (pm_it->second == delete_this_id) {
        port_map.erase(pm_it->first);
    }
}

更新:当然,我然后 read this question我不认为这会相关,但回答了我的问题。

最佳答案

C++11

这已在 C++11 中得到修复(或者删除已得到改进/在所有容器类型中保持一致)。
erase 方法现在返回下一个迭代器。

auto pm_it = port_map.begin();
while(pm_it != port_map.end())
{
    if (pm_it->second == delete_this_id)
    {
        pm_it = port_map.erase(pm_it);
    }
    else
    {
        ++pm_it;
    }
}

C++03

删除映射中的元素不会使任何迭代器失效。
(除了被删除元素上的迭代器)

实际上插入或删除不会使任何迭代器失效:

另请参阅此答案:
Mark Ransom Technique

但是你确实需要更新你的代码:
在您的代码中,您在调用删除后递增 pm_it。此时为时已晚,已经失效。

map<string, SerialdMsg::SerialFunction_t>::iterator pm_it = port_map.begin();
while(pm_it != port_map.end())
{
    if (pm_it->second == delete_this_id)
    {
        port_map.erase(pm_it++);  // Use iterator.
                                  // Note the post increment.
                                  // Increments the iterator but returns the
                                  // original value for use by erase 
    }
    else
    {
        ++pm_it;           // Can use pre-increment in this case
                           // To make sure you have the efficient version
    }
}

关于c++ - 如果在从头到尾迭代时在 map 元素上调用 erase() 会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50612924/

相关文章:

c++ - 在内循环中使用 OpenMP 时性能不佳

c++ - Caffe::net reshape

c++ - 有没有快速创建集合的方法?

c++ - 对迭代器的钳制是否有效

java - 将 ArrayList 嵌入式循环转换为 Iterator

c++ - 如何以编程方式防止 linux 计算机休眠或打开屏幕保护程序?

c++ - C++ 中 'cout<<cout' 和 'cout<<&cout' 的区别?

c++ - STL + typedefs 与 OOP,最佳实践?

python 现在,接下来,n 次迭代

c++ - 嵌套迭代器错误