C++11容器中新增加的emplace相关函数的使用

2023-11-01

C++11中,针对顺序容器(如vector、deque、list),新标准引入了三个新成员:emplace_front、emplace和emplace_back,这些操作构造而不是拷贝元素。这些操作分别对应push_front、insert和push_back,允许我们将元素放置在容器头部、一个指定位置之前或容器尾部。

当调用push或insert成员函数时,我们将元素类型的对象传递给它们,这些对象被拷贝到容器中而当我们调用一个emplace成员函数时,则是将参数传递给元素类型的构造函数。emplace成员使用这些参数在容器管理的内存空间中直接构造元素。

emplace函数的参数根据元素类型而变化,参数必须与元素类型的构造函数相匹配。emplace函数在容器中直接构造元素。传递给emplace函数的参数必须与元素类型的构造函数相匹配。

其它容器中,std::forward_list中的emplace_after、emplace_front函数,std::map/std::multimap中的emplace、emplace_hint函数,std::set/std::multiset中的emplace、emplace_hint,std::stack中的emplace函数,等emplace相似函数操作也均是构造而不是拷贝元素。

emplace相关函数可以减少内存拷贝和移动。当插入rvalue,它节约了一次move构造,当插入lvalue,它节约了一次copy构造。

下面是从其他文章中copy的测试代码,详细内容介绍可以参考对应的reference:

#include "emplace.hpp"
#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <tuple>
#include <utility>

namespace emplace_ {

/
// reference: http://www.cplusplus.com/reference/vector/vector/emplace_back/
int test_emplace_1()
{
{
	/*
		template <class... Args>
		void emplace_back (Args&&... args);
	*/
	std::vector<int> myvector = { 10, 20, 30 };

	myvector.emplace_back(100);
	myvector.emplace_back(200);

	std::cout << "myvector contains:";
	for (auto& x : myvector)
		std::cout << ' ' << x;
	std::cout << '\n';
}

{
	/*
		template <class... Args>
		iterator emplace (const_iterator position, Args&&... args);
	*/
	std::vector<int> myvector = { 10, 20, 30 };

	auto it = myvector.emplace(myvector.begin() + 1, 100);
	myvector.emplace(it, 200);
	myvector.emplace(myvector.end(), 300);

	std::cout << "myvector contains:";
	for (auto& x : myvector)
		std::cout << ' ' << x;
	std::cout << '\n';
}

	return 0;
}

///
// reference: http://en.cppreference.com/w/cpp/container/vector/emplace_back
namespace {
struct President {
	std::string name;
	std::string country;
	int year;

	President(std::string p_name, std::string p_country, int p_year)
		: name(std::move(p_name)), country(std::move(p_country)), year(p_year)
	{
		std::cout << "I am being constructed.\n";
	}
	President(President&& other)
		: name(std::move(other.name)), country(std::move(other.country)), year(other.year)
	{
		std::cout << "I am being moved.\n";
	}
	President& operator=(const President& other) = default;
};
}

int test_emplace_2()
{
	/*
		The following code uses emplace_back to append an object of type President to a std::vector.
		It demonstrates how emplace_back forwards parameters to the President constructor and shows
		how using emplace_back avoids the extra copy or move operation required when using push_back.
	*/
	std::vector<President> elections;
	std::cout << "emplace_back:\n";
	elections.emplace_back("Nelson Mandela", "South Africa", 1994);

	std::vector<President> reElections;
	std::cout << "\npush_back:\n";
	reElections.push_back(President("Franklin Delano Roosevelt", "the USA", 1936));

	std::cout << "\nContents:\n";
	for (President const& president : elections) {
		std::cout << president.name << " was elected president of "
			<< president.country << " in " << president.year << ".\n";
	}
	for (President const& president : reElections) {
		std::cout << president.name << " was re-elected president of "
			<< president.country << " in " << president.year << ".\n";
	}

	return 0;
}


// reference: https://stackoverflow.com/questions/4303513/push-back-vs-emplace-back
int test_emplace_3()
{
	/*
		template <class... Args>
		pair<iterator,bool> emplace (Args&&... args);
	*/
	typedef std::tuple<int, double, std::string> Complicated;

	std::map<int, Complicated> m;
	int anInt = 4;
	double aDouble = 5.0;
	std::string aString = "C++";

	// cross your finger so that the optimizer is really good
	//m.insert(/*std::make_pair*/std::pair<int, Complicated>(4, Complicated(anInt, aDouble, aString)));
	m.insert(std::make_pair(4, Complicated(anInt, aDouble, aString)));

	// should be easier for the optimizer
	m.emplace(6, Complicated(anInt, aDouble, aString));
	/*
		std::piecewise_construct: This constant value is passed as the first argument to construct a pair object
		to select the constructor form that constructs its members in place by forwarding the elements of two
		tuple objects to their respective constructor.
	*/
	m.emplace(std::piecewise_construct, std::make_tuple(8), std::make_tuple(anInt, aDouble, aString));

	return 0;
}

//
// reference: https://corecplusplustutorial.com/difference-between-emplace_back-and-push_back-function/
namespace {
class Dat {
	int i;
	std::string ss;
	char c;

public:
	Dat(int ii, std::string s, char cc) :i(ii), ss(s), c(cc) { }

	~Dat() { }
};
}

int test_emplace_4()
{
	std::vector<Dat> vec;
	vec.reserve(3);

	vec.push_back(Dat(89, "New", 'G')); // efficiency lesser
	//vec.push_back(678, "Newer", 'O'); // error,push_back can’t accept three arguments
	vec.emplace_back(890, "Newest", 'D'); // work fine, efficiency is also more

	return 0;
}

} // namespace emplace_

GitHubhttps://github.com/fengbingchun/Messy_Test  

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++11容器中新增加的emplace相关函数的使用 的相关文章

  • C++11中std::condition_variable的使用

  • C++11中enum class的使用

    枚举类型 enumeration 使我们可以将一组整型常量组织在一起 和类一样 每个枚举类型定义了一种新的类型 枚举属于字面值常量类型 C 包含两种枚举 限定作用域的和不限定作用域的 这里主要介绍限定作用域的 不限定作用域的使用可以参考 h
  • C++中static_cast/const_cast/dynamic_cast/reinterpret_cast的区别和使用

    C风格的强制转换较简单 如将float a转换为int b 则可以这样 b int a 或者b int a C 类型转换分为隐式类型转换和显示类型转换 隐式类型转换又称为标准转换 包括以下几种情况 1 算术转换 在混合类型的算术表达式中 最
  • C++/C++11中头文件algorithm的使用

  • C++11中模板类std::enable_shared_from_this的使用

    C 11中的模板类template
  • C++中namespace detail或namespace internal的使用

    在很多开源代码中偶尔会使用名字为 detail 或 internal 的命名空间 如OpenCV的modules目录中 有些文件中使用了namespace detail 有些文件中使用了namespace internal 名为detail
  • 在Ubuntu 18.04上支持C++17的std::filesystem的方法

    在Ubuntu 18 04上通过命令sudo apt install gcc g 安装的gcc g 版本为7 5 此版本并不直接支持filesystem 如下图所示 Ubuntu 18 04上的g 7 5支持experimental的fil
  • C++11中std::future的使用

    C 11中的std future是一个模板类 std future提供了一种用于访问异步操作结果的机制 std future所引用的共享状态不能与任何其它异步返回的对象共享 与std shared future相反 std future r
  • C和C++安全编码笔记:指针诡计

    指针诡计 pointer subterfuge 是通过修改指针值来利用程序漏洞的方法的统称 可以通过覆盖函数指针将程序的控制权转移到攻击者提供的外壳代码 shellcode 当程序通过函数指针执行一个函数调用时 攻击者提供的代码将会取代原本
  • C++11中std::function的使用

    类模版std function是一种通用 多态的函数封装 std function的实例可以对任何可以调用的目标实体进行存储 复制 和调用操作 这些目标实体包括普通函数 Lambda表达式 函数指针 以及其它函数对象等 通过std func
  • C++/C++11中引用的使用

    引用 reference 是一种复合类型 compound type 引用为对象起了另外一个名字 引用类型引用 refer to 另外一种类型 通过将声明符写成 d的形式来定义引用类型 其中d是声明的变量名 一 一般引用 一般在初始化变量时
  • C和C++安全编码笔记:并发

    并发是一种系统属性 它是指系统中几个计算同时执行 并可能彼此交互 一个并发程序通常使用顺序线程和 或 进程的一些组合来执行计算 其中每个线程和进程执行可以在逻辑上并行执行的计算 这些进程和 或 线程可以在单处理器系统上使用分时抢占式的方式
  • Effective C++改善程序与设计的55个具体做法笔记

    Scott Meyers大师Effective三部曲 Effective C More Effective C Effective STL 这三本书出版已很多年 后来又出版了Effective Modern C More Effective
  • C++中的内存对齐介绍

    网上有很多介绍字节对齐或数据对齐或内存对齐的文章 虽然名字不一样 但是介绍的内容大致都是相同的 这里以内存对齐相称 注 以下内容主要来自网络 内存对齐 通常也称为数据对齐 是计算机对数据类型合法地址做出了一些限制 要求某种类型对象的地址必须
  • C++中插件使用举例

    插件并不是在构建时链接的 而是在运行时发现并加载的 因此 用户可以利用你定义好的插件API来编写自己的插件 这样他们就能以指定方式扩展API的功能 插件库是一个动态库 它可以独立于核心API编译 在运行时根据需要显示加载 不过插件也可以使用
  • 程序员的自我修养--链接、装载与库笔记:目标文件里有什么

    编译器编译源代码后生成的文件叫做目标文件 目标文件从结构上讲 它是已经编译后的可执行文件格式 只是还没有经过链接的过程 其中可能有些符号或有些地址还没有被调整 其实它本身就是按照可执行文件格式存储的 只是跟真正的可执行文件在结构上稍有不同
  • C++/C++11中头文件iterator的使用

  • C++11中std::shared_future的使用

    C 11中的std shared future是个模板类 与std future类似 std shared future提供了一种访问异步操作结果的机制 不同于std future std shared future允许多个线程等待同一个共
  • C++14中binary literals的使用

    一个形如42的值被称作字面值常量 literal 这样的值一望而知 每个字面值常量都对应一种数据类型 字面值常量的形式和值决定了它的数据类型 我们可以将整型字面值写作十进制 基数为10 八进制 基数为8 或十六进制 基数为16 数的形式 以
  • 提高C++性能的编程技术笔记:单线程内存池+测试代码

    频繁地分配和回收内存会严重地降低程序的性能 性能降低的原因在于默认的内存管理是通用的 应用程序可能会以某种特定的方式使用内存 并且为不需要的功能付出性能上的代价 通过开发专用的内存管理器可以解决这个问题 对专用内存管理器的设计可以从多个角度

随机推荐

  • 【python】CliffWalking悬崖寻路问题

    强化学习 简介 gym库 CliffWalking SARSA Q learning 示例 SARSA Q learning 简介 机器学习 监督学习 非监督学习 强化学习 模仿人类和动物的试错机制进行学习 智能体与环境交互 根据当前的环境
  • 数据结构面试常见问题总结

    数据结构面试常见问题总结 写在前面 本文记录了一些数据结构面试常见问题 本意用于考研复试 以下面试题为网上整理的问题以及自己加入的一些问题 答案仅供参考 Q 数据结构三要素 A 逻辑结构 物理结构 数据运算 Q 数组与链表有什么区别 A 数
  • innovus中常用命令整理

    restoreDesign load 之前的db list property type 列举出相应的属性 get property 得到相应的object的属性 get pin 获取pin get port 获取port ecoRoute
  • 2023开学礼山东财经大学《乡村振兴战略下传统村落文化旅游设计》许少辉新财经图书馆

    2023开学礼山东财经大学 乡村振兴战略下传统村落文化旅游设计 许少辉新财经图书馆
  • adworld攻防世界 reverse asong

    asong 攻防世界 reverse 进阶区 asong 题目文件 https www jianguoyun com p DQ3g5b4QiNbmBxjX fQC 访问密码 AgV9Sh 主要是集中我们常见的处理方式的整合 注意一个对于ou
  • 进程间通信---管道通信

    进程间通信为什么有那么多不同的方法 资源的不同 所以通信的方式不同 想要获取管道资源 就需要用管道来通信 想要获取消息队列资源 就需要用消息队列来通信 如上所示 一个进程就是一个PCB PCB中的file struct有三个默认文件描述符
  • 【转】 如何提高自己的acm个人能力

    转载自 简单de数字 最终编辑 fading code by zfy0701 本来以为HNU的huicpc035和我一样退役了 后来听说他组成了新的footman队 于是又关注了下他 035体现了两个我觉得非常重要的品质 1 刻苦的训练 2
  • vmtools的安装和使用

    介绍 vmtools工具是在虚拟系统和主机系统进行共享文件夹的工具 1 用root用户登录CentOS后删除桌面的光驱 2 点击菜单栏的虚拟机 gt 安装VMwareTools 3 安装结果如下所示 4 打开VMwareTools 复制VM
  • 【python】Something is wrong with the numpy installation

    2020年2月5日 0次阅读 共448个字 0条评论 0人点赞 QueenDekimZ COCO API windows下安装COCO API时 python setup py build ext install 出现报错 ImportEr
  • Unity中UI框架的使用3-主界面中的弹窗和关闭

    效果图 在主页面点击排位赛按钮 就会弹出图2中的一个弹窗 再点击弹窗右上角的关闭按钮 就会关闭弹窗 回到图3的效果 方法 1 将PopUp这个面板添加到UIPanelType cs文件中 并且将其名称和路径添加到UIPanelType js
  • Python高级函数1:使用 map()、reduce()、filter()、zip() 和 enumerate() 简化代码

    Python高级函数1 使用 map reduce filter zip和 enumerate 简化代码 1 原理 1 1 map 函数 1 2 reduce 函数 1 3 filter 函数 1 4 zip 函数 1 5 enumerat
  • 在分布式环境下标准支付流程的梳理

    支付流程图的梳理 https www processon com diagraming 61a18a895653bb136f893ecc 提交订单 当用户点击立即购买或者提交订单的这个时候数据库就会记录一笔订单 此项业务主要是用到了rabb
  • Android 设置ListView不可滚动 及在ScrollView中不可滚动的设置

    转载请注明出处 http blog csdn net androiddevelop article details 38815493 希望得到的效果是ListView不能滚动 但是最大的问题在与ListView Item还必有点击事件 如果
  • 2023华为OD机试真题【区间交叠/贪心算法】【Python Java C++】

    题目描述 给定坐标轴上的一组线段 线段的起点和终点均为整数并且长度不小于1 请你从中找到最少数量的线段 这些线段可以覆盖住所有线段 输入描述 第一行输入为所有线段的数量 不超过10000 后面每行表示一条线段 格式为 x y x和y 分别表
  • vscode因网络下载失败的问题

    复制出失败的下载链接 https az764295 vo msecnd net stable d045a5eda657f4d7b676dedbfa7aab8207f8a075 VSCodeUserSetup x64 1 72 2 exe 将
  • 多任务视频推荐方案,百度工程师实战经验分享

    推荐系统的应用场景非常广泛 比如非常火爆的短视频推荐 电商平台商品推荐 搜索推荐等 但是你知道吗 短视频APP在向你展示一个你感兴趣的视频之前 通常既要预测你对这个视频是否感兴趣 又要预测你会看多久 点赞还是不点赞 会不会偷偷收藏起来下次接
  • 迁移学习matlab

    迁移学习是一种机器学习技术 它可以利用已有的模型和数据来加速新模型的训练 在Matlab中实现迁移学习 需要先选定一个预训练的模型 然后使用该模型的权重来初始化新模型 最后对新模型进行微调以适应特定的任务 Matlab中有一些已经预先训练好
  • 常用函数式接口

    常用函数式接口 JDK 8 中重要的函数接口 接口 参数 返回 中文 示例 Supplier None T 提供者 工厂方法创建对象 Consumer T void 消费者 输出一个值 Predicate T boolean 谓语 顾名思义
  • 【Linux】编译器gcc和g++与调试器gdb的使用

    文章目录 一 Linux编译器 gcc g 1 程序运行的四个阶段 1 1 预处理 1 2 编译 1 3 汇编 1 4 链接 2 链接方式与函数库 2 1 动态链接与静态链接 2 2 动态库与静态库 3 gcc g 的使用 二 Linux调
  • C++11容器中新增加的emplace相关函数的使用

    C 11中 针对顺序容器 如vector deque list 新标准引入了三个新成员 emplace front emplace和emplace back 这些操作构造而不是拷贝元素 这些操作分别对应push front insert和p