emplace_back 和 push_back 的区别
C++11 STL
emplace_back 和 push_back
-
直接插入对象,两个是没有区别的
-
给emplace传入Test对象构造所需要的参数,直接在容器底层构造对象即可
假设 vector 中元素类型是类类型,那么 emplace_back() 待添加的元素的类型是类中有参构造的参数类型时,emplace_back() 比 push_back() 少一次移动或拷贝构造函数。而如果添加的元素是类类型的对象时,则和 push_back() 一样都只会调用一次移动构造函数或一次拷贝构造函数(取决于左值还是右值)。
涉及知识点
万能引用 / 引用折叠,完美转发,移动构造函数
源码均基于 vs2019 平台 vector 文件
push_back源码
- push_back是vector的一个普通成员函数,有2个重载,分别接受左值和右值
template <class _Ty, class _Alloc = allocator<_Ty>>...void push_back(const _Ty& _Val) {
// insert element at end, provide strong guaranteeemplace_back(_Val);}void push_back(_Ty&& _Val) {
// insert by moving into element at end, provide strong guaranteeemplace_back(_STD move(_Val)); // 保持原来的右值}
emplace_back源码
- 只有一个模板 利用了 引用折叠 + 可变参数模板
- 进行传递时用了完美转发 —— 保持参数的引用类型
public:template <class... _Valty>decltype(auto) emplace_back(_Valty&&... _Val) {
// insert by perfectly forwarding into element at end, provide strong guaranteeauto& _My_data = _Mypair._Myval2;pointer& _Mylast = _My_data._Mylast;if (_Mylast != _My_data._Myend) {
return _Emplace_back_with_unused_capacity(_STD forward<_Valty>(_Val)...);}_Ty& _Result = *_Emplace_reallocate(_Mylast, _STD forward<_Valty>(_Val)...);
#if _HAS_CXX17return _Result;
#else // ^^^ _HAS_CXX17 ^^^ // vvv !_HAS_CXX17 vvv(void) _Result;
#endif // _HAS_CXX17}
_Emplace_back_with_unused_capacity 和 _Emplace_reallocate 最后都调用了 _Alty_traits::construct 进行构造