1. 传参方式

使用 insert 为 map 插值时,insert 的传参包含以下几种可能:

  • make_pair 生成对象
  • pair(key_type, value_type) 生成对象
  • pair(const key_type, value_type) 生成对象
  • map<key_type, value_type>::value_type 生成对象

不同的传参,导致不同次数的构造 / 析构函数调用。

2. 测试代码与结果

/*
在 map 中不同的 insert 传参类型,导致的不同次数的构造/析构函数调用。
*/ #include <iostream>
#include <vector>
#include <map>
#include <string> using namespace std; class Data
{
public:
Data(void)
{
cout << "Constructor" << endl;
} Data(const Data& other)
{
cout << "Copy Constructor" << endl;
} Data& operator=(const Data& other)
{
cout << "Assignment operator" << endl;
return *this;
} ~Data(void)
{
cout << "Destructor" << endl;
}
}; class Tracker
{
public:
Tracker(string name)
{
_name = name;
cout << "### Testing " << name << endl;
} ~Tracker(void)
{
cout << "### Done" << endl << endl;
} private:
string _name;
}; int main () {
{
Tracker tracker("insert data using make_pair");
map<int, Data> c;
Data d = Data();
cout << "---- Begin ---- " << endl;
c.insert(make_pair(, d));
cout << "----- End -----" << endl;
} {
Tracker tracker("insert data using pair<key_type, value_type>");
map<int, Data> c;
Data d = Data();
cout << "---- Begin ---- " << endl;
c.insert(pair<int, Data>(, d));
cout << "----- End -----" << endl;
} {
Tracker tracker("insert data using pair<const key_type, value_type>");
map<int, Data> c;
Data d = Data();
cout << "---- Begin ---- " << endl;
c.insert(pair<const int, Data>(, d));
cout << "----- End -----" << endl;
} {
Tracker tracker("insert data using map<key_type, value_type>::value_type");
map<int, Data> c;
Data d = Data();
cout << "---- Begin ---- " << endl;
c.insert(map<int, Data>::value_type(, d));
cout << "----- End -----" << endl;
} return ;
}

3. 调用流程分析

3.1 value_type 2 次 Copy Constructor 产生 1 个临时变量

分解后的 value_type 调用细节对比图

  1. 构造 value_type 的临时变量,一次 Copy Constructor
  2. insert value_type 类型的参数,一次 Copy Constructor
  3. 析构 value_type 的临时变量,一次 Destructor

3.2 pair(const key_type, value_type) 与 value_type 过程相同

原因:value_type 的定义是: pair<const key_type,mapped_type>

参见:http://www.cplusplus.com/reference/map/map/

3.3 pair(key_type, value_type)  3 次 Copy Constructor 产生 2 个临时变量

根据下图的流程拆解可以看出,非 const 的 key_type 导致 insert 过程增加了一次 Copy Constructor

3.4 make_pair 4 次 Copy Constructor 产生 3 个临时变量

新增的一次 Copy Constructor 来自于 make_pair 过程。

make_pair 的过程是:Constructs a pair object with its first element set to x and its second element set to y.

伪代码如下:

template <class T1,class T2>
pair<T1,T2> make_pair (T1 x, T2 y)
{
return ( pair<T1,T2>(x,y) );
}

参见:http://www.cplusplus.com/reference/utility/make_pair/?kw=make_pair

make_pair 时的 key 使用 const 变量,并未能减少 insert 阶段的一次 Copy Constructor

const int k = ;
c.insert(make_pair(k, d));

4. 结果分析

  1. insert 时,如果 key_type 不是 const 类型, 则增加一次 Copy Constructor
  2. make_pair 无法产生 const key_type 的 pair,导致 insert 增加一次 Copy Constructor
  3. map<key, value>::value_type 的 key 是 const 类型,使用简单,性能好。

C++ map.insert 传参类型不同,构造/析构次数不同的更多相关文章

  1. LiveBOS Webservice传参类型为list数组

    昨天有使用soap传输数据到Webservice,其中字符串类型的都已经传输成功,但是有几个参数传输失败,java服务器端收到的空值. 因为我是php的,然后接收端是java制作的,其中有几个参数是l ...

  2. httpclient传参类型与响应参数接收

    https://blog.csdn.net/qq_26562641/article/details/72817457 https://blog.csdn.net/chenjf0221/article/ ...

  3. C++ 传参时传内置类型时用传值(pass by value)方式效率较高

    来源:唐磊的个人博客<C++ 传参时传内置类型时用传值(pass by value)方式效率较高> 在<Effective C++>里提到对内置(C-like)类型在函数传参时 ...

  4. springMVC常用传参总结

    本文介绍了springMVC常用的传参方式和一些注意的事项,页面表单主要以ajax的形式提交. 本帅是个菜鸡,水平有限,若有什么讲得不对或有补充的地方欢迎各位提意见. 一.传递String类型   1 ...

  5. (三)Mybatis类型转换器,接口传参类型,一对一,一对多查询resultMap配置

    Mybatis类型转换器 首先明白什么时候用到它,当数据库的字段类型和java字段类型无法默认匹配时候进行转换,比如现在数据库类型是INTEGER,而java当中类型是Boolean,true表示1, ...

  6. mybatis-plus 自定义SQL,XML形式,传参的几种方式

    mybatis-plus 自定义SQL,XML形式,传参的几种方式 前提说明 所涉及文件 传参类型说明 1.Java代码中使用QueryWrapper动态拼装SQL 2.简单类型参数(如String, ...

  7. SpringMVC前后端分离交互传参详细教程

    温故而知新,本文为一时兴起写出,如有错误还请指正 本文后台基于SpringBoot2.5.6编写,前端基于Vue2 + axios和微信小程序JS版分别编写进行联调测试,用于理解前后端分离式开发的交互 ...

  8. 浅谈对java中传参问题的理解

    之前用的c/c++比较多,在c/c++中对于传参类型,无外乎就是传值.传引用.传指针这几种.但在java中,由于没有指针类型,其传参的方式也发生了相应的变化.在网上找了找,按我之前的理解,java中传 ...

  9. Java的对象传参问题

    在c/c++中对于传参类型,无外乎就是传值.传引用.传指针这几种.但在java中,由于没有指针类型,其传参的方式也发生了相应的变化.之前有搜过相关的知识点一直理解的是:Java的传参方式中主要有两种: ...

随机推荐

  1. Ant-常用命令(笔记二)

    1.copy命令: <?xml version="1.0" encoding="utf-8"?> <project name="co ...

  2. SAP增强总结-第二代增强(SMOD、CMOD)【转载】

    第二代增强比第二代增强安全性提高了很多,第一代增强毕竟是在原标准程序中修改,大部分传递参数都可以直接使用,第二代增强做了一些封装,对用户可以修改的参数做了限制. 1.增强点查找方法 首先根据事物码找到 ...

  3. iOS开发——UI篇OC篇&UIDynamic详解

    iOS开发拓展篇—UIDynamic(简单介绍) 一.简单介绍 1.什么是UIDynamic UIDynamic是从iOS 7开始引入的一种新技术,隶属于UIKit框架 可以认为是一种物理引擎,能模拟 ...

  4. mysqldump原理5

    http://blog.csdn.net/niu870781892/article/details/6186078 导出多张表的时候表之间用空格分开: # mysqldump -h192.168.25 ...

  5. C 高级编程4 makefile 与 IO

    make 与 makefile .目标的语法 目标名:依赖目标 @命令 @命令 make的命令行使用 make -f make 脚本文件 目标名 .目标的划分 demo.mk demo: gcc -c ...

  6. servlet 容器,工作原理,优缺点

    转自http://blog.sina.com.cn/s/blog_b5a157500101ld71.html servlet:是以java技术为基础,应用于服务器端的程序组件,本质就是java代码,用 ...

  7. linux服务器上apache+php独立于mysql server单独部署

    1. mysql client 2. libmysqlclient-devel 3. PDO_MYSQL

  8. debian 颜色设置

    root@debian:/# vi /root/.bashrc #export PS1='\h:\w\$ 'export PS1='\[\033[1;32;40m\]\u@\h:\w\$ \[\033 ...

  9. Python基础:1.数据类型(空、布尔类型、整型、长整型、浮点型、字符串)

    提示:python版本2.7,windows系统 Python提供的基本数据类型:空.布尔类型.整型.长整型.浮点型.字符串.列表.元组.字典.日期 1.空(None) None,是一个特殊的值,不能 ...

  10. 面试之SQL

    1. 查询性能优化:从数据库查询数据时,你一定遇到过查询很慢的情况,请问你是怎么处理的. 答: 遇到的问题描述:是遇到过这种情况,我们给客户做过一款软件,日志库搜集了6000万条数据,显示.查询时候慢 ...