STL emplace_back

一 介绍

C++11开始,STL的一些容器中增加了emplace和emplace_back成员函数,例如 std::list 和 std::vector。

 以 std::vector::emplace_back举例:

template< class... Args >
void emplace_back( Args&&... args ); (C++11 起) (C++17 前)
template< class... Args >
reference emplace_back( Args&&... args ); (C++17 起)

从C++17开始,改变了返回值,返回被插入元素的引用。

emplace_back 添加新元素到容器尾。元素通过 std::allocator_traits::construct 构造,它典型地用布置 new 于容器所提供的位置原位构造元素。参数 args... 以 std::forward(args)... 转发到构造函数。

二 emplace_back 和 push_back

简单来说,emplace_back是在容器所提供的位置直接构造,而push_back添加一个新元素到vector末尾,然后拷贝或者移动到新元素。

#include 
#include 

class A {
 public:
  A() {
    std::cout << "constructor" << std::endl;
  }
  A(int n) {
    std::cout << "constructor int" << std::endl;
  }
  A(const A& a) {
    std::cout << "copy constructor" << std::endl;
  }
  ~A() {
    std::cout << "destructor" << std::endl;
  }
};

int main() {
  A a;
  {
    std::vector vc;
    vc.reserve(10); // 排除扩容干扰
    std::cout << std::endl;
    std::cout << "push_back:" << std::endl;
    vc.push_back(1);
    vc.push_back(a);
  }

  {
    std::vector vc1;
    vc1.reserve(10);
    std::cout << std::endl;
    std::cout << "emplace_back:" << std::endl;
    vc1.emplace_back(1);
    vc1.emplace_back(a);
  }

  std::cin.get();
  return 0;
}

STL emplace_back_第1张图片

在push_back中先用参数1构造一个临时的A实例,然后拷贝到vector,最后析构临时的A实例;而emplace_back仅用参数1原位构造了一个A实例。对于插入a,表现一致,都是调用A的拷贝构造函数。

所以在支持emplace_back的场景下,推荐用emplace_back代替push_back。

你可能感兴趣的:(#,STL)