1. 序列容器
主要是vector和deque
vector中内存连续,所以插入、删除、扩容后都会导致原迭代器失效。
deque的使用方式和vector类似。
// 假如想删除大于5的元素
vector<int> vec{ 1,2,3,4,5,6,7,8,9,10 };
// 错误写法1,迭代器失效会导致报错
/*for (auto it = vec.begin(); it != vec.end(); ++it) {if (*it > 5) vec.erase(it);
}*/
// 错误写法2,删除元素会跳着删,并且也会报错
/*for (auto it = vec.begin(); it != vec.end();++it) {if (*it > 5) it = vec.erase(it);
}*/// 正确写法
for (auto it = vec.begin(); it != vec.end();) {if (*it > 5) it = vec.erase(it); // 获得下一个有效迭代器else ++it;
}
for (auto num : vec) {cout << num << " "; // 输出 1 2 3 4 5
}
2. 链式容器
对于链表式容器(如 list),删除当前的 iterator,仅仅会使当前的 iterator 失效,插入、删除都不会对其他节点造成影响。
list<int> arr{ 1,2,3,4,5,6,7,8,9,10 };// 第一种方式,和vector一样,获得下一个有效迭代器
for (auto it = arr.begin(); it != arr.end();) {if (*it > 5) it=arr.erase(it); // 获得下一个有效迭代器else ++it;
}
// 第二种方式,递增迭代器
for (auto it = arr.begin(); it != arr.end();) {if (*it > 5) arr.erase(it++); // 递增迭代器else ++it;
}
for (auto num : arr) {cout << num << " ";
}
3. 关联式容器
map, set,multimap,multiset,删除当前的 iterator,仅仅会使当前的 iterator 失效,只要在 erase 时,递增当前 iterator 即可。但是要注意:erase 迭代器只使被删元素的迭代器失效,但是返回值为 void,所以要采用erase(iter++)的方式删除迭代器。
unordered_map的删除也类似。
map<int, int> arr = { {1, 12}, {2, 23}, {3, 34}, {4, 45}, {5, 56}, {6, 67} };//for (auto it = arr.begin(); it != arr.end();++it) {
// if (it->second>30) arr.erase(it); // erase后,it就失效了,就无法++it,就会导致报错
//}
// 正确做法
for (auto it = arr.begin(); it != arr.end();) {if (it->second > 30) arr.erase(it++);else ++it;
}
for (auto num : arr) {cout << num.first << " " << num.second << endl;
}
总结
以vector为代表的序列容器,插入、删除都会导致之后的迭代器失效,扩容会导致所有迭代器失效。
而list、map等容器,都只是使得当前插入、删除的迭代器失效。
代码实现都使用if else对要删除的情况进行处理。对于vector使用获得下一个迭代器的方式,对于list、map使用迭代器递增的方式。