大多数情况下,emplace_back的消耗小于等于push_back。emplace_back会避免中间零时变量的构造。
    摘以下MinGW的std::vector的实现

    1. void
    2. push_back(const value_type& __x)
    3. {
    4. if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
    5. {
    6. _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
    7. __x); // 复制构造
    8. ++this->_M_impl._M_finish;
    9. }
    10. else
    11. _M_realloc_insert(end(), __x);
    12. }
    13. void
    14. push_back(value_type&& __x)
    15. { emplace_back(std::move(__x)); }
    16. void
    17. vector<_Tp, _Alloc>::
    18. emplace_back(_Args&&... __args)
    19. {
    20. if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
    21. {
    22. _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
    23. std::forward<_Args>(__args)...); // 移动构造
    24. ++this->_M_impl._M_finish;
    25. }
    26. else
    27. _M_realloc_insert(end(), std::forward<_Args>(__args)...);
    28. }
    1. std::vector<std::string> vs;
    2. std::string s = "Hi";
    3. vs.push_back(s); // 调用左值形参的push_back
    4. vs.push_back(s + "123"); // 调用右值形参的push_back
    5. vs.push_back("Hello"); // 首先构造一个string类型的tmp临时对象,然后调用右值形式的push_back,实际调用到
    6. // emplace_back,并将tmp移入容器内,之后析构tmp(一次构造一次移动一次析构)
    7. vs.emplace_back("Hello"); // 将右值“Hello”完美转发进容器内,在容器内用“Hello”作为实参调用string对象的接受
    8. // const char * 形参的构造函数,没有临时对象生成(一次构造)