C++ STL map emplace()和emplace_hint()(深入了解,一文学会)

        C++ STL Map模板类中除了 insert() 方法 还提供了 emplace() emplace_hint() 成员函数,也可以实现向 map 容器中插入新的键值对。本节就来讲解这 2 个成员方法的用法。

值得一提的是,实现相同的插入操作,无论是用 emplace() 还是 emplace_hont(),都比 insert() 方法的效率高后半篇会详解。

和 insert() 方法相比,emplace() 和 emplace_hint() 方法的使用要简单很多,因为它们各自只有一种语法格式。其中,emplace() 方法的语法格式如下:

template <class... Args>
  pair<iterator,bool> emplace (Args&&... args);

参数 (Args&&... args) 指的是,这里只需要将创建新键值对所需的数据作为参数直接传入即可,此方法可以自行利用这些数据构建出指定的键值对。另外,该方法的返回值也是一个 pair 对象,其中 pair.first 为一个迭代器,pair.second 为一个 bool 类型变量:

  • 当该方法将键值对成功插入到 map 容器中时,其返回的迭代器指向该新插入的键值对,同时 bool 变量的值为 true;
  • 当插入失败时,则表明 map 容器中存在具有相同键的键值对,此时返回的迭代器指向此具有相同键的键值对,同时 bool 变量的值为 false。

  本文作者原创,转载请附上文章出处与本文链接。

 C++ STL map emplace()和emplace_hint()(深入了解,一文学会)目录

1. emplace()

 2. emplace_hint()

 3. map容器的三种插入方式insert emplace emplace_hint效率对比


1. emplace()

	//创建并初始化 map 容器
	map<string, string>mymap;
	//插入键值对
	pair<map<string, string>::iterator, bool> ret = mymap.emplace("csdn", "https://blog.csdn.net/qq_37529913?spm=1001.2101.3001.5343");
	cout << "1、ret.iter = <{" << ret.first->first << ", " << ret.first->second << "}, " << ret.second << ">" << endl;
	//插入新键值对
	ret = mymap.emplace("C++", "https://blog.csdn.net/qq_37529913?spm=1001.2101.3001.5343");
	cout << "2、ret.iter = <{" << ret.first->first << ", " << ret.first->second << "}, " << ret.second << ">" << endl;
	//失败插入的样例
	ret = mymap.emplace("QT", "https://blog.csdn.net/qq_37529913?spm=1001.2101.3001.5343");
	cout << "3、ret.iter = <{" << ret.first->first << ", " << ret.first->second << "}, " << ret.second << ">" << endl;
	cout << "-------------------------------------------------------------------" << endl;
	cout << "-------------------------------------------------------------------" << endl;
    //程序中共执行了 3 次向 map 容器插入键值对的操作,其中前 2 次都成功了,第 3 次由于要插入的键值对的键和 map 容器中已存在的键值对的键相同,因此插入失败。

 2. emplace_hint()

	//创建并初始化 map 容器
	std::map<string, string>mymap;
	//指定在 map 容器插入键值对
	map<string, string>::iterator iter = mymap.emplace_hint(mymap.begin(), "csdn", "https://blog.csdn.net/qq_37529913?spm=1001.2101.3001.5343");
	cout << iter->first << " " << iter->second << endl;
	iter = mymap.emplace_hint(mymap.begin(), "C++", "https://blog.csdn.net/qq_37529913?spm=1001.2101.3001.5343");
	cout << iter->first << " " << iter->second << endl;
	//插入失败样例
	iter = mymap.emplace_hint(mymap.begin(), "QT", "https://blog.csdn.net/qq_37529913?spm=1001.2101.3001.5343");
	cout << iter->first << " " << iter->second << endl;
	cout << "-------------------------------------------------------------------" << endl;
	cout << "-------------------------------------------------------------------" << endl;
    //和 insert() 方法一样,虽然 emplace_hint() 方法指定了插入键值对的位置,但 map 容器为了保持存储键值对的有序状态,可能会移动其位置。

 3. map容器的三种插入方式insert emplace emplace_hint效率对比

        以下内容借鉴自:https://blog.csdn.net/qq_44004011/article/details/115359611

#include <iostream>
#include <map>  //map
#include <string> //string
using namespace std;

class testDemo
{
public:
    testDemo(int num) :num(num) {
        std::cout << "调用构造函数" << endl;
    }
    testDemo(const testDemo& other) :num(other.num) {
        std::cout << "调用拷贝构造函数" << endl;
    }
    testDemo(testDemo&& other) :num(other.num) {
        std::cout << "调用移动构造函数" << endl;
    }
private:
    int num;
};

int main()
{
    //创建空 map 容器
    std::map<std::string, testDemo>mymap;

    cout << "insert():" << endl;
    mymap.insert({ "http://c.biancheng.net/stl/", testDemo(1) });
   
    cout << "emplace():" << endl;
    mymap.emplace( "http://c.biancheng.net/stl/:", 1);

    cout << "emplace_hint():" << endl;
    mymap.emplace_hint(mymap.begin(), "http://c.biancheng.net/stl/", 1);
    return 0;
}

 在使用 insert() 方法向 map 容器插入键值对时,整个插入过程调用了 1 次 tempDemo 类的构造函数,同时还调用了 2
次移动构造函数。实际上,程序第 28 行代码底层的执行过程,可以分解为以下 3 步:

//构造类对象
testDemo val = testDemo(1); //调用 1 次构造函数
//构造键值对
auto pai = make_pair("http://c.biancheng.net/stl/", val); //调用 1 次移动构造函数
//完成插入操作
mymap.insert(pai); //调用 1 次移动构造函数

而完成同样的插入操作,emplace() 和 emplace_hint() 方法都只调用了 1 次构造函数,这足以证明,这 2 个方法是在
map 容器内部直接构造的键值对。

结论:C++11新增的emplace() 和 emplace_hint()都比insert效率高

使用 insert() 向 map 容器中插入键值对的过程是,先创建该键值对,然后再将该键值对复制或者移动到 map 容器中的指定位置;

使用 emplace() 或 emplace_hint() 插入键值对的过程是,直接在 map 容器中的指定位置构造该键值对。

因此,在实现向 map 容器中插入键值对时,应优先考虑使用 emplace() 或者 emplace_hint()。

以下博客部分内容借鉴自:http://c.biancheng.net/stl/。

C++ STL 容器、迭代器、适配器(深入了解,一文学会)    https://blog.csdn.net/qq_37529913/article/details/120052137                                                                                C++ STL deque容器(深入了解,一文学会)                       https://blog.csdn.net/qq_37529913/article/details/118676574
C++ STL vector容器(深入了解,一文学会)                       https://blog.csdn.net/qq_37529913/article/details/118676109
C++ STL list容器(深入了解,一文学会)                             https://blog.csdn.net/qq_37529913/article/details/118676917
C++ STL forward_list容器(深入了解,一文学会)               https://blog.csdn.net/qq_37529913/article/details/118687348
C++ STL array 容器(深入了解,一文学会)                        https://blog.csdn.net/qq_37529913/article/details/118688364
C++ STL pair 类模板(深入了解,一文学会)                       https://blog.csdn.net/qq_37529913/article/details/118714852
C++ STL map容器(深入了解,一文学会)                           https://blog.csdn.net/qq_37529913/article/details/118741670
C++ STL map emplace()和emplace_hint()(深入了解,一文学会)         https://blog.csdn.net/qq_37529913/article/details/118771777
C++ STL multimap容器(深入了解,一文学会)                    https://blog.csdn.net/qq_37529913/article/details/118773021
C++ STL Set容器(深入了解,一文学会)                             https://blog.csdn.net/qq_37529913/article/details/118918940
C++ STL multiset容器(深入了解,一文学会)                      https://blog.csdn.net/qq_37529913/article/details/119624779
C++ STL unordered_map容器(深入了解,一文学会)         https://blog.csdn.net/qq_37529913/article/details/119689199
C++ STL unordered_set容器(深入了解,一文学会)           https://blog.csdn.net/qq_37529913/article/details/119709019
C++ STL unordered_multiset容器(深入了解,一文学会)    https://blog.csdn.net/qq_37529913/article/details/119709079
C++ STL stack容器适配器(深入了解,一文学会)        https://blog.csdn.net/qq_37529913/article/details/119723782
C++ STL queue容器适配器(深入了解,一文学会)       https://blog.csdn.net/qq_37529913/article/details/119746246
C++ STL priority_queue容器适配器(深入了解,一文学会)                https://blog.csdn.net/qq_37529913/article/details/119770527
C++ STL reverse_iterator反向迭代器适配器(深入了解,一文学会)   https://blog.csdn.net/qq_37529913/article/details/119814820
C++ STL insert_iterator插入迭代器适配器(深入了解,一文学会)      https://blog.csdn.net/qq_37529913/article/details/119834378
C++ STL stream_iterator流迭代器(深入了解,一文学会)                  https://blog.csdn.net/qq_37529913/article/details/119834429
C++ STL streambuf_iterator流缓冲区迭代器(深入了解,一文学会)        https://blog.csdn.net/qq_37529913/article/details/119850048
C++ STL move_iterator移动迭代器(深入了解,一文学会)                      https://blog.csdn.net/qq_37529913/article/details/119859888
C++ STL advance()函数(深入了解,一文学会)        https://blog.csdn.net/qq_37529913/article/details/120008250
C++ STL distance()函数(深入了解,一文学会)        https://blog.csdn.net/qq_37529913/article/details/120008300
C++ STL iterator迭代器(深入了解,一文学会)         https://blog.csdn.net/qq_37529913/article/details/120008346
C++ STL const_iterator转换为iterator类型迭代器(深入了解,一文学会)        https://blog.csdn.net/qq_37529913/article/details/120008324
C++ STL begin()和end()函数(深入了解,一文学会)        https://blog.csdn.net/qq_37529913/article/details/120008459
C++ STL prev()和next()函数(深入了解,一文学会)         https://blog.csdn.net/qq_37529913/article/details/120008481

  • 8
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

双子座断点

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值