当前位置: 首页 > 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.lryc.cn/news/595378.html

相关文章:

  • Go语言的包
  • TSN(时间敏感网络)协议栈在STM32平台(尤其是STM32MP2系列)上的实现
  • 设备虚拟化技术-IRF
  • C++ 中的默认构造函数:非必要,不提供
  • 苍穹外卖Day5
  • B树、B+树的区别及MySQL为何选择B+树
  • Git核心功能简要学习
  • GraphRAG快速入门和原理理解
  • 关于JVM
  • AXI接口学习
  • 上网行为管理-身份认证1
  • 剖析Sully.ai:革新医疗领域的AI助手功能启示
  • Hyperledger Fabric V2.5 生产环境部署及安装Java智能合约
  • 【OD机试】模拟数据序列号传输
  • 09_Spring Boot 整合 Freemarker 模板引擎的坑
  • 用简鹿视频格式转换器轻松制作 GIF 表情包教程
  • 牛客周赛 Round 101(题解的token计算, 76修地铁 ,76选数,76构造,qcjj寄快递,幂中幂plus)
  • 解决vscode中vue格式化后缩进太小的问题,并去除分号 - 设置Vetur tabSize从2到4,设置prettier取消分号semi
  • 元宇宙工厂漫游指南:VR可视化在设备巡检与远程运维中的沉浸式应用
  • zabbix企业级分布式监控
  • Java 实现 UDP 多发多收通信
  • C++unordered系列的map和set类(封装)
  • WAMP配置局域网https服务
  • C# 实现:动态规划解决 0/1 背包问题
  • Nacos 探活机制深度解析:临时 / 永久实例差异及与 Sentinel 的熔断协作
  • OpenAI API(1)补全Responses(Chat Completions)API和记忆Assistants API对比分析
  • Java 大视界 -- 基于 Java 的大数据分布式计算在地球物理勘探数据处理与地质结构建模中的应用(356)
  • 16 BTLO 蓝队靶场 Drill Down 解题记录
  • 前缀和题目:元素和小于等于阈值的正方形的最大边长
  • 计算机发展史:互联网时代的万物互联与全球变革