大多数情况下,emplace_back的消耗小于等于push_back。emplace_back会避免中间零时变量的构造。
摘以下MinGW的std::vector的实现
voidpush_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);}voidpush_back(value_type&& __x){ emplace_back(std::move(__x)); }voidvector<_Tp, _Alloc>::emplace_back(_Args&&... __args){if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage){_Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,std::forward<_Args>(__args)...); // 移动构造++this->_M_impl._M_finish;}else_M_realloc_insert(end(), std::forward<_Args>(__args)...);}
std::vector<std::string> vs;std::string s = "Hi";vs.push_back(s); // 调用左值形参的push_backvs.push_back(s + "123"); // 调用右值形参的push_backvs.push_back("Hello"); // 首先构造一个string类型的tmp临时对象,然后调用右值形式的push_back,实际调用到// emplace_back,并将tmp移入容器内,之后析构tmp(一次构造一次移动一次析构)vs.emplace_back("Hello"); // 将右值“Hello”完美转发进容器内,在容器内用“Hello”作为实参调用string对象的接受// const char * 形参的构造函数,没有临时对象生成(一次构造)
