我是靠谱客的博主 曾经书本,最近开发中收集的这篇文章主要介绍emplace_back 和 push_back 的区别,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

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 guarantee
        emplace_back(_Val);
    }

    void push_back(_Ty&& _Val) { // insert by moving into element at end, provide strong guarantee
        emplace_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 guarantee
        auto& _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_CXX17
        return _Result;
#else // ^^^ _HAS_CXX17 ^^^ // vvv !_HAS_CXX17 vvv
        (void) _Result;
#endif // _HAS_CXX17
    }

_Emplace_back_with_unused_capacity 和 _Emplace_reallocate 最后都调用了 _Alty_traits::construct 进行构造

最后

以上就是曾经书本为你收集整理的emplace_back 和 push_back 的区别的全部内容,希望文章能够帮你解决emplace_back 和 push_back 的区别所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(71)

评论列表共有 0 条评论

立即
投稿
返回
顶部