STL迭代器失效场景全面总结
请全面总结C++ STL各容器在插入(Insert)和删除(Erase)操作时迭代器失效的规则,并给出安全的遍历删除代码示例。
回答
屠龙少年
各容器迭代器失效规则: | 容器 | 插入失效 | 删除失效 | |------|---------|---------| | vector | 所有迭代器(扩容时);插入点之后(未扩容) | 被删元素及之后所有迭代器 | | deque | 所有迭代器(非首尾);首尾插入可能失效部分(控制块重组) | 被删元素及附近迭代器 | | list | 永不失效 | 仅被删元素 | | forward_list | 永不失效 | 仅被删元素前驱的next | | map/set | 永不失效 | 仅被删元素 | | unordered_map/set | 仅rehash时全部失效 | 仅被删元素 |
安全遍历删除:
// vector/map/set
for (auto it = c.begin(); it != c.end(); ) {
if (condition) it = c.erase(it); // erase返回下一个有效迭代器
else ++it;
}
// C++20 erase_if 更简洁
std::erase_if(vec, [](int x){ return x % 2 == 0; });
// list特有 remove_if
lst.remove_if([](int x){ return x > 10; });
注意:遍历过程中不要修改会导致rehash/重新分配的容器(unordered_map的插入可能rehash)。