emplace_back和push_back超详细讲解+常见问题分析[more cpp-5]

2024-08-25 09:04

本文主要是介绍emplace_back和push_back超详细讲解+常见问题分析[more cpp-5],希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

也是深入研究上标准库了啊,XDM ♪(´▽`)

这两个函数都是在容器的尾部插入对象,不过push_back是早期的函数(为CPP98,就是第一个CPP标准化版本),emplace_back则是在CPP11加入的重要特性,是CPP高性能化的重要特征。简单的来说

  • push_back是传入一个对象,而后在容器的尾部拷贝一个出来
  • emplace_back是传入构造对象的参数,然后直接在对象尾部直接构造出来这个对象

emplace_back优化了什么问题?

假如我们有类OBJ

class OBJ
{
public:OBJ(int a, string name_):age(a),name(name_){cout << "Build function is called   "<<name_ << endl;}OBJ(const OBJ& obj){cout << "copy fun is called   "<<obj.name << endl;age = obj.age;name = obj.name;}int age;string name;
};

如果在算法之中,我们需要向容器中插入对象

	vector<OBJ> vect;vect.push_back(OBJ{ 114,"str" });

运行一下

Build function is called   str
copy fun is called   str

你会发现,这里有一次不必要的性能浪费:我们先构造出来匿名对象OBJ,然后再拷贝它一次放在尾端,这不是折腾吗。当然,如果你是把一个具名对象拷贝到数组中去,那是另当别论了。所以我们在这种情况下,最好在容器的尾部直接构造对象,避免拷贝

意料之外的事故

emplace_back真的这么好用吗?没有需要注意的地方吗?

int main() {vector<OBJ> vect;vect.push_back(OBJ{ 114,"str" });//vect.push_back(12, "Bob"); 参数类型不匹配cout << "__________________" << endl;vect.emplace_back(14, "anye");return 0;
}

运行一下

Build function is called   str
copy fun is called   str
__________________
Build function is called   anye
copy fun is called   str

为啥anye也是先构造,再拷贝呢?很简答,vector空间(capacity不够了),只能先构造再拷贝了,所以要先用reserve预留好空间楼主的的对resevere resize的解析,包看包会

int main() {vector<OBJ> vect;vect.reserve(2);vect.push_back(OBJ{ 114,"str" });cout << "__________________" << endl;vect.emplace_back(14, "anye");return 0;
}

运行结果

Build function is called   str
copy fun is called   str
__________________
Build function is called   anye

这不就完美了?ヾ(•ω•`)o

这篇关于emplace_back和push_back超详细讲解+常见问题分析[more cpp-5]的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1105123

相关文章

Python包管理工具核心指令uvx举例详细解析

《Python包管理工具核心指令uvx举例详细解析》:本文主要介绍Python包管理工具核心指令uvx的相关资料,uvx是uv工具链中用于临时运行Python命令行工具的高效执行器,依托Rust实... 目录一、uvx 的定位与核心功能二、uvx 的典型应用场景三、uvx 与传统工具对比四、uvx 的技术实

canal实现mysql数据同步的详细过程

《canal实现mysql数据同步的详细过程》:本文主要介绍canal实现mysql数据同步的详细过程,本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的... 目录1、canal下载2、mysql同步用户创建和授权3、canal admin安装和启动4、canal

SpringBoot集成LiteFlow实现轻量级工作流引擎的详细过程

《SpringBoot集成LiteFlow实现轻量级工作流引擎的详细过程》LiteFlow是一款专注于逻辑驱动流程编排的轻量级框架,它以组件化方式快速构建和执行业务流程,有效解耦复杂业务逻辑,下面给大... 目录一、基础概念1.1 组件(Component)1.2 规则(Rule)1.3 上下文(Conte

Springboot3+将ID转为JSON字符串的详细配置方案

《Springboot3+将ID转为JSON字符串的详细配置方案》:本文主要介绍纯后端实现Long/BigIntegerID转为JSON字符串的详细配置方案,s基于SpringBoot3+和Spr... 目录1. 添加依赖2. 全局 Jackson 配置3. 精准控制(可选)4. OpenAPI (Spri

MyBatis Plus 中 update_time 字段自动填充失效的原因分析及解决方案(最新整理)

《MyBatisPlus中update_time字段自动填充失效的原因分析及解决方案(最新整理)》在使用MyBatisPlus时,通常我们会在数据库表中设置create_time和update... 目录前言一、问题现象二、原因分析三、总结:常见原因与解决方法对照表四、推荐写法前言在使用 MyBATis

Python主动抛出异常的各种用法和场景分析

《Python主动抛出异常的各种用法和场景分析》在Python中,我们不仅可以捕获和处理异常,还可以主动抛出异常,也就是以类的方式自定义错误的类型和提示信息,这在编程中非常有用,下面我将详细解释主动抛... 目录一、为什么要主动抛出异常?二、基本语法:raise关键字基本示例三、raise的多种用法1. 抛

MySQL复杂SQL之多表联查/子查询详细介绍(最新整理)

《MySQL复杂SQL之多表联查/子查询详细介绍(最新整理)》掌握多表联查(INNERJOIN,LEFTJOIN,RIGHTJOIN,FULLJOIN)和子查询(标量、列、行、表子查询、相关/非相关、... 目录第一部分:多表联查 (JOIN Operations)1. 连接的类型 (JOIN Types)

github打不开的问题分析及解决

《github打不开的问题分析及解决》:本文主要介绍github打不开的问题分析及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、找到github.com域名解析的ip地址二、找到github.global.ssl.fastly.net网址解析的ip地址三

SpringBoot整合Apache Flink的详细指南

《SpringBoot整合ApacheFlink的详细指南》这篇文章主要为大家详细介绍了SpringBoot整合ApacheFlink的详细过程,涵盖环境准备,依赖配置,代码实现及运行步骤,感兴趣的... 目录1. 背景与目标2. 环境准备2.1 开发工具2.2 技术版本3. 创建 Spring Boot

使用Python实现base64字符串与图片互转的详细步骤

《使用Python实现base64字符串与图片互转的详细步骤》要将一个Base64编码的字符串转换为图片文件并保存下来,可以使用Python的base64模块来实现,这一过程包括解码Base64字符串... 目录1. 图片编码为 Base64 字符串2. Base64 字符串解码为图片文件3. 示例使用注意