首页 > 编程语言 >C++学习随笔——关联容器的迭代器失效问题

C++学习随笔——关联容器的迭代器失效问题

时间:2024-08-27 16:36:49浏览次数:8  
标签:std 迭代 删除 元素 C++ 失效 myMap 随笔

常见关联容器的迭代器失效规则
std::map 和 std::set:

插入元素:
插入新元素不会使任何已有的迭代器失效。你可以在插入新元素后继续使用所有现有的迭代器。

删除元素:
删除某个元素会导致指向该元素的迭代器失效。除此之外,所有指向其他元素的迭代器仍然有效。
如果在遍历过程中删除元素,应该小心处理迭代器。通常做法是使用 erase 函数时,将其返回值(下一个有效迭代器)赋给当前迭代器。

点击查看代码
#include <iostream>
#include <map>

int main() {
    std::map<int, std::string> myMap = {{1, "one"}, {2, "two"}, {3, "three"}};

    for (auto it = myMap.begin(); it != myMap.end(); ) {
        if (it->first == 2) {
            it = myMap.erase(it);  // 删除后 it 被更新为指向下一个元素的迭代器
        } else {
            ++it;
        }
    }

    for (const auto& pair : myMap) {
        std::cout << pair.first << ": " << pair.second << std::endl;
    }

    return 0;
}

点击查看代码
#include <iostream>
#include <unordered_map>

int main() {
    std::unordered_map<int, std::string> myMap = {{1, "one"}, {2, "two"}, {3, "three"}};

    for (auto it = myMap.begin(); it != myMap.end(); ) {
        if (it->first == 2) {
            it = myMap.erase(it);  // 删除后 it 被更新为指向下一个元素的迭代器
        } else {
            ++it;
        }
    }

    for (const auto& pair : myMap) {
        std::cout << pair.first << ": " << pair.second << std::endl;
    }

    return 0;
}

如何避免迭代器失效问题

在插入操作后:

对于 std::map、std::set,不需要特别处理,插入操作不会使现有迭代器失效。
对于 std::unordered_map 和 std::unordered_set,在插入操作后,如果需要继续使用迭代器,建议重新获取或避免频繁插入操作。

在删除操作后:

始终使用 erase 返回的迭代器(指向删除元素后的下一个有效元素)继续遍历。不要尝试使用指向已删除元素的迭代器。

在遍历容器时:

如果要在遍历时修改容器,尤其是删除操作,确保迭代器的安全性,遵循上面提到的规则。
使用 std::vector 等序列容器时,删除操作可能导致所有迭代器失效,应特别注意。

标签:std,迭代,删除,元素,C++,失效,myMap,随笔
From: https://www.cnblogs.com/kitanoki/p/18383017

相关文章

  • 从零开始学习C++之递归
    递归注:此算法与函数有关,如不了解请移步。在wikipedia中,递归的解释是这样的:在C++中,递归就是指在函数中调用函数本身;递归的作用类似于分治,将一个大问题分解为很多小问题进行求解。但是递归的时间复杂度极高,因为要解决很多小问题,所以时间复杂度高达\(O(2^n)\)。使用递......
  • C++/Qt 多媒体(续二)
    一、前言        前边讲述到了Qt的两项独特的模块编程支持的另一项内容——多媒体编程,上篇文章具体讲述的包括一个QMediaPlayer类的示例代码和一个QSoundEffect类的讲解,而本章将会提供一篇示例代码——《基于QMediaRecorder类的音频录制》。    对于上篇内......
  • C++面试基础系列-this指针
    系列文章目录文章目录系列文章目录C++面试基础系列-this指针Overview1.this指针1.1.特性1.2.用法1.3.注意事项2.使用'this'指针的多态类的示例3.在C++中,指针和对象本身有什么区别?关于作者C++面试基础系列-this指针Overview1.this指针在C++中,this指针是一......
  • c/c++代码流程图生成
    以下介绍2款皆免费1.cxx2flow【github项目】c/c++函数解析为dot然后通过Graphviz渲染项目有附带gui程序可直接生成流程图,但是显示效果缩放不太行,建议解析生成dot后喂给其他基于Graphviz的渲染服务,使用过vscode上面的graphviz-interactive-preview,效果还行,也有在线网页渲染......
  • 【编程规范具体案例(基于Qt、微软、谷歌和AUTOSAR C++14 参考)】 C++ 编码规范 之并发篇
    目录标题并发目录12.并发编程规范12.1线程创建与管理规则12.1.1\[必须]明确定义线程的生命周期管理策略12.1.2\[必须]为关键线程设置明确的标识符12.1.3\[必须]在多线程环境中安全地处理异常12.2线程同步规则12.2.1\[必须]使用线程安......
  • C++与C语言中基础数据类型详解
    目录引言基础数据类型分类实际编程中的应用建议结论引言在C++与C语言的编程世界中,理解并正确使用基础数据类型是每个程序员的必备技能。不同的数据类型在内存中的占用和表示方式直接影响到程序的性能和行为。本文将详细介绍C++与C语言中常见的基础数据类型,探讨它们......
  • C++ lambda
    文章目录基本语法捕捉列表函数对象与lambda表达式C++的lambda表达式是C++11及以后版本中引入的一种强大的特性,它提供了一种简洁的方式来定义匿名函数对象。Lambda表达式能够捕获其所在作用域中的变量(以值或引用的方式),并允许你在需要函数对象的地方(比如算法库中的函数......
  • C++常见内存错误及其对策
    常见内存错误及其对策目录常见内存错误及其对策内存分配未成功,却使用了它内存分配成功但未初始化内存操作越界内存泄漏释放内存后继续使用规则总结图表示C++学习资料在软件开发过程中,内存管理是至关重要的一环。内存错误不仅会导致程序崩溃,还可能引发安全问题。本文......
  • c++教程之三大结构
    C++顺序结构教程在编程的世界里,顺序结构是构建所有程序的基础。无论是简单的脚本还是复杂的应用程序,它们都是由一系列按照特定顺序执行的指令组成的。C++,作为一种高效、灵活的编程语言,同样遵循这一原则。本教程将深入介绍C++中的顺序结构,包括变量与数据类型、运算符与表达式、......
  • C++笔记9•list•
    容器之list1.list的介绍(1).list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。(2).list的底层是双向循环链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素。(3).优......