1.42、vector中的push_back()和emplace_back()的区别
机制区别
- • push_back
先构造一个临时对象(通常通过拷贝或移动构造函数),然后将该对象拷贝或移动到容器内部。
例如:v.push_back(T(args));
会先创建临时T
对象,再移动或拷贝进vector
。 - • emplace_back
直接在容器尾部内存位置原地构造对象,通过完美转发传递构造函数参数,避免了临时对象的创建和移动。
例如:v.emplace_back(args);
直接调用T
的构造函数在容器内构造。
性能影响
- •
emplace_back
通常减少一次额外的构造或移动操作,在构造复杂对象时更高效。 - •
push_back
在已有对象(尤其是右值或临时对象)时,性能差异不明显,因为移动构造可以高效转移资源。 - • 编译器优化可能缩小两者差距,但
emplace_back
的设计目标是避免不必要的临时对象。
使用场景建议
场景 | 推荐使用 | 说明 |
已有一个完整对象,需要将其加入容器 | push_back |
直接传入对象或右值,语义清晰且安全 |
需要直接传递构造参数,在容器内原地构造 | emplace_back |
避免临时对象,提升性能,适合复杂对象或非拷贝构造类型 |
对象构造函数是显式(explicit ) |
emplace_back |
push_back 无法隐式调用显式构造函数,emplace_back 可直接转发参数 |
代码可读性和维护性优先 | push_back (默认) |
语义简单,编译器对模板推导负担更小,调试更友好 |
示例
struct Widget {
Widget(int x, double y);
// ...
};
std::vector<Widget> v;
// 使用push_back,需要先构造临时对象
v.push_back(Widget(42, 3.14)); // 先构造临时Widget,再移动到vector
// 使用emplace_back,直接在vector尾部构造
v.emplace_back(42, 3.14); // 直接调用Widget(int, double)构造函数,无临时对象
总结
- •
emplace_back
的优势在于避免临时对象的构造和移动,适合直接传递构造参数原地构造新元素。 - •
push_back
适合已有对象的插入,语义更明确且更安全。 - • 在大多数日常场景中,
push_back
足够且易于理解;当性能敏感或需要直接构造复杂对象时,优先考虑emplace_back
。
本文首发于【讳疾忌医-note】公众号,未经授权,不得转载。
(加入我的知识星球,免费获取账号,解锁所有文章。)
阅读剩余
版权声明:
作者:讳疾忌医-note
链接:https://www.1217zy.vip/archives/1324
文章版权归作者所有,未经允许请勿转载。
THE END