C++ map容器插入操作方式详解

 更新时间:2025年05月19日 10:20:52   作者:苕皮蓝牙土豆  
map是C++ STL中的关联容器,存储键值对(key-value pairs),下面给大家介绍C++ map容器插入操作方式,感兴趣的朋友一起看看吧

1. map插入操作基础

map是C++ STL中的关联容器,存储键值对(key-value pairs)。插入元素时有四种主要方式,各有特点:

1.1 头文件与声明

#include <map>
using namespace std;
map<int, string> mapStu;  // 键为int,值为string

2. 四种插入方式详解

2.1 方式一:构造pair后插入

pair<map<int, string>::iterator, bool> ret = 
    mapStu.insert(pair<int, string>(1, "张三"));

特点

  • 显式构造pair对象
  • insert返回一个pair<iterator, bool>
    • first:指向插入元素的迭代器
    • second:是否插入成功(bool)

示例判断

if (ret.second == true) {
    cout << "插入成功!value:" << (*(ret.first)).second << endl;
} else {
    cout << "插入失败!" << endl;  // 键已存在时会失败
}

注意:对于map,如果键已存在,插入会失败,不会覆盖原有值。

2.2 方式二:使用make_pair

mapStu.insert(make_pair(2, "李四"));

优点

  • 语法更简洁,无需显式指定模板参数
  • 自动推导pair类型
  • 同样返回pair<iterator, bool>

2.3 方式三:使用value_type

mapStu.insert(map<int, string>::value_type(3, "王五"));

特点

  • value_type是map内部定义的typedef,等同于pair<const Key, T>
  • 类型安全,确保键的类型正确
  • 同样返回pair<iterator, bool>

2.4 方式四:使用[]操作符

mapStu[4] = "赵六";      // 插入
mapStu[4] = "小赵六";    // 修改

关键特性

  • 查找+插入/修改:先查找键是否存在,不存在则插入,存在则修改
  • 可能意外插入:访问不存在的键时会自动插入
string strName = mapStu[8];  // 键8不存在时会自动插入

返回值:返回值的引用,可直接修改

特殊用法

mapStu[6] = mapStu[5];  // 复制键5的值到键6
mapStu[7] = mapStu[4];  // 复制键4的值到键7

3. 四种方式对比

特性方式一(pair)方式二(make_pair)方式三(value_type)方式四([])
语法复杂度
返回值pair<iter,bool>pair<iter,bool>pair<iter,bool>值引用
键存在时的行为不覆盖不覆盖不覆盖覆盖
可能意外插入
类型安全性最高
性能中等中等中等稍快

4. 遍历map内容

for (map<int, string>::iterator it = mapStu.begin(); 
     it != mapStu.end(); it++) {
    cout << it->first << ", " << it->second << endl;
}

或使用C++11范围for循环:

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

5. 关键注意事项

  • 键的唯一性map中每个键只能出现一次,重复插入会失败
  • 自动排序:元素按键的升序自动排列
  • []操作符的风险
    • 可能意外插入新元素
    • 访问不存在的键时会用默认值创建新元素
  • 性能考虑
    • 插入操作平均时间复杂度O(log n)
    • 对于已知不存在的键,使用insert[]更高效

6. 实际应用建议

  • 需要知道是否插入成功:使用insert+检查返回值
  • 需要覆盖现有值:使用[]操作符
  • 避免意外插入:先用find检查键是否存在
  • 代码简洁性:优先考虑make_pairemplace(C++11)

7. 完整代码回顾

#include <map>
#include <iostream>
using namespace std;
int main() {
    map<int, string> mapStu;
    // 方式一
    auto ret = mapStu.insert(pair<int, string>(1, "张三"));
    if (ret.second) {
        cout << "插入成功!value:" << ret.first->second << endl;
    } else {
        cout << "插入失败!" << endl;
    }
    // 重复插入测试
    ret = mapStu.insert(pair<int, string>(1, "小张三"));
    if (!ret.second) {
        cout << "插入小张三失败!" << endl;
    }
    // 方式二
    mapStu.insert(make_pair(2, "李四"));
    // 方式三
    mapStu.insert(map<int, string>::value_type(3, "王五"));
    // 方式四
    mapStu[4] = "赵六";
    mapStu[4] = "小赵六";  // 覆盖
    // 特殊用法
    mapStu[6] = mapStu[5];  // 复制
    mapStu[7] = mapStu[4];  // 复制
    // 遍历输出
    for (const auto& pair : mapStu) {
        cout << pair.first << ", " << pair.second << endl;
    }
    system("pause");
    return 0;
}

8. 扩展知识

8.1 C++11的emplace

C++11引入了更高效的emplace方法:

mapStu.emplace(5, "钱七");  // 直接在容器内构造元素,避免临时对象

8.2 异常安全性

insertemplace提供强异常保证:如果插入失败,容器保持不变。

8.3 性能优化

对于大批量插入:

如果键已知有序,可以使用提示位置插入:

mapStu.insert(hint_iterator, make_pair(10, "孙八"));

或者先构建vector再批量插入

到此这篇关于C++ map容器: 插入操作的文章就介绍到这了,更多相关C++ map容器插入内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • c++实现简单的线程池

    c++实现简单的线程池

    这里给大家介绍了C++中对于pthread线程的一个简单应用以及使用继承CDoit,实现其中的start和end,有需要的小伙伴可以参考下
    2015-11-11
  • 基于C语言实现钻石棋游戏的示例代码

    基于C语言实现钻石棋游戏的示例代码

    独立钻石是源于18世纪法国的宫廷贵族的自我挑战类单人棋游戏,可以锻炼逻辑思维能力。本文将用C语言实现这一简单的游戏,感兴趣的小伙伴可以了解一下
    2023-02-02
  • 深入理解C++ 字符变量取地址的特殊性与内存管理机制详解

    深入理解C++ 字符变量取地址的特殊性与内存管理机制详解

    在 C++ 编程中,字符变量的取地址行为和内存布局对程序行为有着深远的影响,尤其是在打印变量地址和访问内存内容时,本文将给大家介绍C++ 字符变量取地址的特殊性与内存管理机制,感兴趣的朋友一起看看吧
    2024-12-12
  • C++封装线程类的实现方法

    C++封装线程类的实现方法

    这篇文章主要介绍了C++封装线程类的实现方法,实例介绍了针对线程的创建、调用等方法的封装操作,需要的朋友可以参考下
    2014-10-10
  • 举例分析private的作用(c/c++学习)

    举例分析private的作用(c/c++学习)

    我知道我们可以用 public 中的值,把private中的数据给提出来,但是还是搞不懂private该怎么用,或者说在一个具体程序中,private有什么用
    2020-08-08
  • C++类的构造与析构特点及作用详解

    C++类的构造与析构特点及作用详解

    本文章将会可能会涉及到汇编的知识,不过没有关系,我会讲的尽量通俗易懂;另外本篇文章开始前,建议了解下什么是函数重载,这个概念很简单的--有相同的函数名,但参数列表不相同的函数,就是函数重载
    2022-10-10
  • C++超详细分析红黑树

    C++超详细分析红黑树

    这一篇我要跟大家介绍二叉搜索树中的另一颗树——红黑树,它主要是通过控制颜色来控制自身的平衡,但它的平衡没有AVL树的平衡那么严格
    2022-03-03
  • 详解C语言printf()输出格式

    详解C语言printf()输出格式

    这篇文章主要介绍了C语言printf()输出格式,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-03-03
  • vscode+qt5+cmake编译调试过程解析

    vscode+qt5+cmake编译调试过程解析

    这篇文章主要介绍了vscode+qt5+cmake编译调试过程解析,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-03-03
  • C语言实现简易的三子棋小游戏

    C语言实现简易的三子棋小游戏

    这篇文章主要为大家详细介绍了C语言实现简易的三子棋小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08

最新评论