有一个 std::map 需要被绕过,如果它们的值满足某个条件,则删除一些元素。通常在基于 tange 的循环中进行遍历并直接在循环中删除元素是有效的(这对我来说完全是一个惊喜)。但是这种行为在多大程度上是正确的呢?据我所知,这样的循环只是迭代器遍历的包装。为什么删除值后迭代器不会死?
int main() {
std::map<int, string> some_map;
for (int i = 0; i < 10; i++) some_map.emplace(i, std::to_string(i));
for (auto& [first, second] : some_map) if (!second.compare("6")) some_map.erase(first);
for (auto [first, second] : some_map) std::cout << first<< " " << second << std::flush << std::endl;
return 0;
}
这些动作是不正确的。迭代器死了。程序本身陷入了未定义行为的深渊。
正如文档所说,“对已擦除元素的引用和迭代器无效。其他引用和迭代器不受影响。”
这意味着您的循环不正确,因为它删除了隐藏迭代器指向的元素。它按预期为您工作的事实只不过是一个意外。
但是,如果您将迭代器提前到下一个元素,它将保持有效并且循环将是正确的:
您还可以使用文档中的示例: