当前位置: 首页 > news >正文

C++11 emplace_back和push_back区别

Hello!!大家早上中午晚上好!!今天我们来看看emplace_back到底是什么?

一、看原型

1.1emplace_back原形(list容器下)

1.2push_back原形(list容器下)

前面已经复习过万能引用、引用折叠了所以对于emplace_back中Args&&表示的意思不多解释,我们来着重看模版参数中的 Args前的...和函数中跟在Args&&后面的...三个点,什么意思?

二、可变参数模版

2.1C++11新增的可变参数模版概念

在定义模版的时候可以这么定义:

template <class... Argus>

Argus是模版参数包,...Argus表示拥有0到N个任意来类型参数的参数包;

也可以这么定义:

template<calss T,class... Argus>

Argus是模版参数包,...Argus表示拥有1到N个任意类型参数的参数包;因为在Argus之前定义了一个T

以此类推:

template<class T1,class T2,class... Arugs>

Argus是个模版参数包,拥有过2到N个任意类型参数的参数包

...

2.2如何拿到参数包里的参数?

方法一:递归方式展开

void Print()
{
	cout << endl;
}
template <class T,class ...Args>
void Print(T first,Args... args)
{
	cout << first <<" ";
	Print(args...);
}
int main()
{
	Print(10);
	Print(10, 11.1);
	Print(10, 11.1, "hello");
	return 0;
}

运行:

递归方式的缺点就是必须要重载一个终止递归的函数(当参数为0);

方法二:逗号表达式+列表初始化


template<class ...Argu>
void Print(Argu... argu)
{
	initializer_list<int> il = { (cout << argu << " ",0)...};
	cout << endl;
}
int main()
{
	Print(1);
	Print(1,2.2);
	Print(1,2.2,"hello");
	return 0;
}

运行:

注:

逗号表达式运行结果为最后一个值,会把逗号分隔的内容按顺序运行一遍;

列表初始化保证初始化的值必须从左往右;

三、emplace_back 和push_back区别

3.1、emplace_back是函数模版,且是可变参数模版,通过传入不同参数类型,实例化出不同类型的emplace_back函数;push_back是类成员函数;
3.2、empalec_back底层:

emplace_back 函数的参数类型是可变数量的 万能引用,参数通过 完美转发 到容器 内部进行对象创建构造,可以有效减少参数传递过程中产生临时对象,避免了对象的移动和拷贝操作。

push_back在参数传递的过程中会产生临时对象,增加拷贝构造或移动构造的操作;

测试:

#include <vector>
class testDimo
{
public:
	testDimo(int id)
		:_id(id)
	{
		cout << "普通构造" << endl;
	}
	testDimo(const testDimo&t)
		: _id ( t._id)
	{
		cout << "拷贝构造" << endl;
	}
	testDimo(testDimo&& t)
		:_id(t._id)
	{
		cout << "移动构造" << endl;
	}
private:
	int _id;
};
int main()
{
	vector<testDimo>v1;
	v1.push_back(1);
	cout << endl;
	vector<testDimo>v2;
	v2.emplace_back(1);
	return 0;

运行:

3.3总结

emplace_back相比于push_back只是减少了拷贝构造或移动构造的操作而已;

只要我们实现了移动构造,push_back的代价跟emplace_back不会相差太多!

相关文章:

  • 2025-03-16 学习记录--C/C++-PTA 习题4-4 特殊a串数列求和
  • 电子元器件的假冒翻新防护
  • 【C++】string类讲解:含常用接口使用及原理模拟实现
  • 案例驱动的 IT 团队管理:创新与突破之路:第一章 重构 IT 团队管理:从传统到创新-1.1.3 敏捷开发 vs 传统流程
  • NAT、代理服务器、内网穿透和内网打洞
  • [生活] 如何区分 s ms us ns
  • 基于消失点标定前视相机外参
  • android 后台下载任务,断点续传
  • “driver-class-name: com.mysql.cj.jdbc.Driver“报错问题的解决
  • 英语面试常见问题
  • 【软考-架构】7、系统配置与性能评价
  • 03 介绍ffmpeg 视频解码流程
  • 3月16号
  • SNX币合规交易突破 XBIT去中心化交易所引领DEX安全新范式
  • 【算法学习之路】10.二叉树
  • 关系数据库设计基础:函数依赖、码与多值依赖详解
  • 大语言模型基础--task2:大模型技术基础
  • 平方矩阵问题
  • AlarmManager添加定时任务
  • 【JavaEE】快速上手JSON:构建高效 Java 后端数据桥梁,开启交互新篇,以 @RequestBody 为引的探索之旅
  • 做网站seo赚钱吗/朋友圈广告推广文字
  • 网站功能建设/深圳在线制作网站
  • 网站建设品牌有哪些/免费发布信息的平台有哪些
  • 搭建一个简单的网站/青岛网站推广系统
  • 青岛做门户网站的有哪些/推广工具
  • dw如何做网站后台/内蒙古网站seo