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

C/C++---emplace和emplace_back

在C++中,emplaceemplace_back是容器(如vectorlistmap等)提供的用于插入元素的成员函数。它们是C++11引入的特性,主要优势在于能够直接在容器的内存位置上构造对象,而不需要先创建临时对象再将其复制或移动到容器中。

1. emplace_back

适用容器vectordequelist 等支持尾部插入的容器。
功能:在容器尾部直接构造一个新元素,参数是元素类型的构造函数参数。

示例

#include <vector>
#include <string>
#include <iostream>struct Person {std::string name;int age;// 构造函数Person(const std::string& n, int a) : name(n), age(a) {}
};int main() {std::vector<Person> people;// 传统方式:先创建临时对象,再移动到容器people.push_back(Person("Alice", 25));// emplace_back 方式:直接在容器内存中构造对象people.emplace_back("Bob", 30); // 直接传递构造函数参数for (const auto& p : people) {std::cout << p.name << ", " << p.age << std::endl;}return 0;
}

输出

Alice, 25
Bob, 30

优势

  • 效率更高:避免了临时对象的创建和移动操作。
  • 语法更简洁:直接传递构造参数,无需显式创建对象。

2. emplace

适用容器:关联容器(如mapset)、无序容器(如unordered_mapunordered_set)、适配器容器(stackqueuepriority_queue)。
功能:在容器的适当位置直接构造一个新元素,参数是元素类型的构造函数参数。

示例(map

std::stack<int> stk;
stk.emplace(42);  // 正确
// stk.emplace_back(42);  // 错误:stack没有emplace_back
#include <map>
#include <string>
#include <iostream>int main() {std::map<int, std::string> myMap;// 传统方式:先创建临时 pair,再插入myMap.insert(std::make_pair(1, "apple"));// emplace 方式:直接构造 pairmyMap.emplace(2, "banana"); // 直接传递 pair 的构造参数for (const auto& pair : myMap) {std::cout << pair.first << ": " << pair.second << std::endl;}return 0;
}

输出

1: apple
2: banana

优势

  • 避免临时对象:对于mapunordered_map,无需显式构造std::pair
  • 自动处理重复键:若键已存在,元素不会插入(与insert行为一致)。

3. 区别与注意事项

特性emplace_backemplace
适用容器序列容器(如vectorlist关联容器(如mapset
插入位置容器尾部自动排序的合适位置(关联容器)
参数元素类型的构造参数元素类型的构造参数
返回值voidpair<iterator, bool>(是否插入成功)
场景推荐方法示例代码
stack/queue 压栈emplacestk.emplace(42);
vector 尾部插入emplace_backvec.emplace_back(42);
vector 任意位置插入emplace(iterator)vec.emplace(vec.begin(), 42);

注意事项

  1. 参数匹配:传递的参数必须能被元素类型的构造函数接受。
  2. 移动语义:若元素类型支持移动构造,push_back/insert 可能也很高效,但emplace仍可能更优。
  3. 异常安全:若构造函数抛出异常,容器状态保持不变。

总结

  • 优先使用 emplace_back/emplace:在性能敏感场景或构造参数复杂时。
  • 兼容性:若需要兼容旧代码或明确依赖临时对象的创建(如触发特定构造函数),仍可使用push_back/insert
http://www.dtcms.com/a/291105.html

相关文章:

  • 企业IT管理——IT系统灾难恢复计划及实施步骤参考模板
  • rk3588 Android 12 添加framework层服务,HAL库,从硬件驱动层到上层APP,实现led灯控
  • OpenAI开发的一款实验性大型语言模型(LLM),在2025年国际数学奥林匹克竞赛(IMO)中达到了金牌水平
  • 数智管理学(三十七)
  • liunx宝塔面板部署easyswoole项目
  • 常规笔记本和加固笔记本的区别
  • React 中使用immer修改state摆脱“不可变”
  • 打造自己的 Jar 文件分析工具:类名匹配 + 二进制搜索 + 日志输出全搞定
  • 从一开始的网络攻防(六):php反序列化
  • UART串口
  • 什么是内网穿透?本地内网无公网IP如何实现互联网上远程访问?
  • 每日一题7.21
  • 自动化商品监控:利用淘宝API开发实时价格库存采集接口
  • springdoc-openapi-ui的使用教程
  • 嵌入式开发学习———Linux环境下C语言学习(十二)
  • 【Tools】Ubuntu24.04安装详细教程
  • mobaxteam x11传输界面避坑
  • SAP 邮箱配置
  • C语言运算符优先级“潜规则”
  • 原型与原型链
  • 二维码扫描登录流程详解
  • 【Elasticsearch】settings
  • 解密分账系统:企业资金管理的智能中枢
  • Linux的相关指令
  • 京东商品评论如何获取?API接口实战指南
  • Kali MSF渗透Windows 11电脑
  • Linux_gdb调试器--进程概念
  • Linux初识网络
  • MySQL 核心知识点梳理(3)
  • buntu 22.04 上离线安装Docker 25.0.5(二)