欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

c++ std::vector 使用push_back 和emplace_back的区别

程序员文章站 2022-03-21 14:34:06
...

首先贴函数的声明和定义部分源码:

template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
class vector : protected _Vector_base<_Tp, _Alloc>
{
      typedef _Tp value_type;

      void  push_back(const value_type& __x)
      {
	    if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
	    {
	        _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
				     __x);
	        ++this->_M_impl._M_finish;
	    }
	    else
	      _M_realloc_insert(end(), __x);
      }

#if __cplusplus >= 201103L
      void
      push_back(value_type&
                & __x)
      { emplace_back(std::move(__x)); }

      template<typename... _Args>
#if __cplusplus > 201402L
	reference
#else
	void
#endif
	emplace_back(_Args&&... __args);
#endif

     // ... 省略
};

 

说说区别:

使用emplace_back比push_back 更加高效。

怎么解释?上一段验证代码:

class Student{
public:

    Student(int age,string name):age_(age),name_(name){
        std::cout << "[" << __FUNCTION__ << ":" << __LINE__  << "    Student(int age,string name)]" << std::endl;
        std::cout << *this << std::endl;
    }

    Student(const Student& that){
        std::cout << "[" << __FUNCTION__ << ":" << __LINE__  << "  Student(const Student& that)]" << std::endl;
        std::cout << that << std::endl;
    }

    ~Student(){
        std::cout << "[" << __FUNCTION__ << ":" << __LINE__  << "  ~Student()]" << std::endl;
        std::cout << *this << std::endl;
    }

    friend ostream& operator <<(ostream& os,const Student& that){
        os << "[" <<__FUNCTION__ << ":" << __LINE__  << "] : " << that.name_ << "    " << that.age_ << endl;
        return os;
    }

private:
    int age_;
    string name_;
};

int main(int argc,char* argv[])
{
    vector<Student> v;

    {
        v.push_back(Student(12,string("zhangsan")));
    }

    {
        //v.emplace_back(12,string("lisi"));
    }
    return 0;
}

输出结果:

分别执行两种插入方式:



[Student:22    Student(int age,string name)]
[operator<<:37] : zhangsan    12

[Student:27  Student(const Student& that)]
[operator<<:37] : zhangsan    12

[~Student:32  ~Student()]
[operator<<:37] : zhangsan    12

[~Student:32  ~Student()]
[operator<<:37] :     7019200

-----------------------------------------------------------

[Student:22    Student(int age,string name)]
[operator<<:37] : lisi    12

[~Student:32  ~Student()]
[operator<<:37] : lisi    12

很明显可以看到,使用emplace_back 比使用push_back要少执行一次拷贝构造和析构