c++ - 'erase' ing 之后的映射迭代器行为

标签 c++ dictionary stl

我在下面写这段代码,发现了这个奇怪的行为:

#include <iostream>
#include <map>
#include <string>
using namespace std;

int main()
{
   map<int, string> map1;
   map1[1] = "Hello";
   map1[2] = "Hello1";
   map1[3] = "Hello2";
   map1[4] = "Hello3";
   map1[5] = "Hello4";

   map<int, string>::iterator it;

   for (it = map1.begin(); it != map1.end(); /*it++*/)
   {
      cout << "Enter: " << (int)(it->first) << endl;
      if (it->first == 3)
         map1.erase(it);
      it++;
      cout << "Exit: " << (int)(it->first) << endl;

   }

   return 0;
}

输出是:

Enter: 1
Exit: 2
Enter: 2
Exit: 3
Enter: 3
Exit: 4
Enter: 4
Exit: 5
Enter: 5
Exit: 4

当我仅在 for 循环中递增迭代器 it 时(检查注释迭代器),输出如下:

Enter: 1
Exit: 1
Enter: 2
Exit: 2
Enter: 3
Exit: 3
Enter: 4
Exit: 4
Enter: 5
Exit: 5

我很困惑,为什么在第一种情况下,当我递增迭代器时,它再次指向之前的 map 元素 4?

最佳答案

两个版本都是未定义的行为,后者似乎有效。

在这两种情况下,你增加一个已经失效的迭代器,
参见示例 iterator invalidation rules
后者的行为不同,因为 'enter' 和 'exit' 正在打印
相同的迭代器

这是通过所有 STL 容器都支持的“迭代删除”习惯用法解决的

// C++11
auto iter = container.begin();
while( iter != container.end() )
{
    if( SomeCondition() )
        iter = container.erase(iter);
    else
        ++iter;
}

这正是 erase 返回迭代器的原因

注意关联容器,例如std::map
在 C++11 之前不支持这个

关于c++ - 'erase' ing 之后的映射迭代器行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28736396/

相关文章:

c++ - 关于自定义分配器和 STL 的模板声明、别名和特化说明

c++ - 苹果图形用户界面编程

c++ - WebView 作为 OSX 应用程序中的 GUI

c++ - 根据#define 切换函数

c++ - 减去 std::strings 时出现编译器错误

python - 如何将 pandas DataFrame 转换为只有值而没有列的 Python 字典?

c++ - STL vector::insert 在 Windows 和 linux 中的区别?

c++ - 为什么字符串和 vector 是不同的类型?

python - 这怎么能写在一行上呢?

android - 如何在 map 上显示路线