C++ STL map insert()插入数据的4种方式

1年前 (2024-04-27)
前面讲过,C++ STL map 类模板中对[ ]运算符进行了重载,即根据使用场景的不同,借助[ ]运算符可以实现不同的操作。举个例子:

#include <iostream>

#include <map> //map

#include <string> //string

using namespace std;

int main()

{

std::map<string, string> mymap{ {"STL教程","http://c.biancheng网站站点" rel="nofollow" /> http://c.biancheng网站站点" rel="nofollow" /> insert() 成员方法,该方法专门用来向 map 容器中插入新的键值对。

注意,这里所谓的“插入”,指的是 insert() 方法可以将新的键值对插入到 map 容器中的指定位置,但这与 map 容器会自动对存储的键值对进行排序并不冲突。当使用 insert() 方法向 map 容器的指定位置插入新键值对时,其底层会先将新键值对插入到容器的指定位置,如果其破坏了 map 容器的有序性,该容器会对新键值对的位置进行调整。

自 C++ 11 标准后,insert() 成员方法的用法大致有以下 4 种。

1) 无需指定插入位置,直接将键值对添加到 map 容器中。insert() 方法的语法格式有以下 2 种:

//1、引用传递一个键值对
pair<iterator,bool> insert (const value_type& val);
//2、以右值引用的方式传递键值对
template <class P>

    pair<iterator,bool> insert (P&& val);

其中,val 参数表示键值对变量,同时该方返回一个 pair 对象,其中 pair.first 表示一个迭代器,pair.second 为一个 bool 类型变量:

  • 如果成功插入 val,则该迭代器指向新插入的 val,bool 值为 true;

  • 如果插入 val 失败,则表明当前 map 容器中存有和 val 的键相同的键值对(用 p 表示),此时返回的迭代器指向 p,bool 值为 false。

以上 2 种语法格式的区别在于传递参数的方式不同,即无论是局部定义的键值对变量还是全局定义的键值对变量,都采用普通引用传递的方式;而对于临时的键值对变量,则以右值引用的方式传参。有关右值引用,可阅读《C++右值引用》一详细了解。

举个例子:

#include <iostream>

#include <map> //map

#include <string> //string

using namespace std;

int main()

{

//创建一个空 map 容器

std::map<string, string> mymap;

//创建一个真实存在的键值对变量

std::pair<string, string> STL = { "STL教程","http://c.biancheng网站站点" rel="nofollow" /> ret.iter = <{STL教程, http://c.biancheng网站站点" rel="nofollow" />

//调用 pair 类模板的构造函数

ret = mymap.insert(pair<string,string>{ "C语言教程","http://c.biancheng网站站点" rel="nofollow" /> //以普通引用的方式传递 val 参数
iterator insert (const_iterator position, const value_type& val);
//以右值引用的方式传递 val 键值对参数
template <class P>

    iterator insert (const_iterator position, P&& val);

其中 val 为要插入的键值对变量。注意,和第 1 种方式的语法格式不同,这里 insert() 方法返回的是迭代器,而不再是 pair 对象:

  • 如果插入成功,insert() 方返回一个指向 map 容器中已插入键值对的迭代器;

  • 如果插入失败,insert() 方法同样会返回一个迭代器,该迭代器指向 map 容器中和 val 具有相同键的那个键值对。


举个例子:

#include <iostream>

#include <map> //map

#include <string> //string

using namespace std;

int main()

{

//创建一个空 map 容器

std::map<string, string> mymap;

//创建一个真实存在的键值对变量

std::pair<string, string> STL = { "STL教程","http://c.biancheng网站站点" rel="nofollow" /> STL教程 http://c.biancheng网站站点" rel="nofollow" />

再次强调,即便指定了新键值对的插入位置,map 容器仍会对存储的键值对进行排序。也可以说,决定新插入键值对位于 map 容器中位置的,不是 insert() 方法中传入的迭代器,而是新键值对中键的值。


3) insert() 方法还支持向当前 map 容器中插入其它 map 容器指定区域内的所有键值对,该方法的语法格式如下:

template <class InputIterator>

  void insert (InputIterator first, InputIterator last);

其中 first 和 last 都是迭代器,它们的组<first,last>可以表示某 map 容器中的指定区域。

举个例子:

#include <iostream>

#include <map> //map

#include <string> //string

using namespace std;

int main()

{

//创建并初始化 map 容器

std::map<std::string, std::string>mymap{ {"STL教程","http://c.biancheng网站站点" rel="nofollow" /> Java教程 http://c.biancheng网站站点" rel="nofollow" /> void insert ({val1, val2, ...});

其中,vali 都表示的是键值对变量。

举个例子:

#include <iostream>

#include <map> //map

#include <string> //string

using namespace std;

int main()

{

//创建空的 map 容器

std::map<std::string, std::string>mymap;

//向 mymap 容器中添加 3 个键值对

mymap.insert({ {"STL教程", "http://c.biancheng网站站点" rel="nofollow" /> C语言教程 http://c.biancheng网站站点" rel="nofollow" />

值得一提的是,除了 insert() 方法,map 类模板还提供 emplace() 和 emplace_hint() 方法,它们也可以完成向 map 容器中插入键值对的操作,且效率还会 insert() 方法高。关于这 2 个方法,会在下一节做详细介绍。