emplace操作
   
C++11新标准引入了三个新成员:emplace、emplace_back、emplace_front,分别对应insert、push_back、push_front
    emplace操作
    
     构造而不拷贝元素
    
   
- 
     调用push或者insert时,将元素类型的对象传递出去,这些对象被
 
 拷贝到容器当中
 
 ,或者创建一个局部临时对象,并将其压入容器
- 
     调用emplace时,
 
 则是将参数传递给元素类型的构造函数
 
 ,emplace成员使用这些参数
 
 在容器管理的内存空间中直接构造元素
 
 ,没有拷贝的操作
代码举例:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
//定义一个student类型
struct student {
  student() = default;
  student(const std::string &str, int num) : name_(str), num_(num) {
      cout << name_ << " constructor called" << endl;
  }
  student(student &stu) {
      this -> name_ = stu.name_;
      this -> num_ = stu.num_;
      cout << name_ << " copy constructor called" << endl;
  }
  student(student &&stu) {
      this -> name_ = stu.name_;
      this -> num_ = stu.num_;
      cout << name_ << " move constructor called" << endl;
  }
  ~student() {
      cout << name_ << " destructor constructor called" << endl;
  }
  std::string name_;
  int num_;
};
int main() {
  vector<student> stu_vec;
  stu_vec.reserve(10); // 不提前reserve会有多次拷贝操作
  cout << "==========emplace_back right val==========" << endl;
  stu_vec.emplace_back(student("lily", 3));
  cout << stu_vec.size() << endl;//size = 1
  stu_vec.emplace_back("bob", 1);//在stu_vec末尾构造一个student对象,使用2个参数的student构造函数
  cout << stu_vec.size() << endl;//size = 2
  cout << "==========push_back right val=========" << endl;
  stu_vec.push_back(student("tom", 2));//正确,创建一个临时的student对象,传递给push_back
  cout << stu_vec.size() << endl;//size = 3
//   stu_vec.push_back("tom", 2);//错误,没有接受2个参数的push_back版本,push不支持直接构造
  cout << "==========emplace_back left val==========" << endl;
  student stu1("mike", 4);
  stu_vec.emplace_back(stu1);
  cout << stu_vec.size() << endl;//size = 4
  cout << "==========push_back left val==========" << endl;
  student stu2("jeck", 5);
  stu_vec.emplace_back(stu2);
  cout << stu_vec.size() << endl;//size = 5
  return 0;
}
    
     reserve操作为容器预留足够的空间,避免不必要的重复分配
    
   
意思就是vector的size超过capacity时会重新进行内存分配(一般是double),并把原有的数据拷贝到新申请的地址。这是vector的实现细节。
- 
reserve() 为容器预留足够的空间,避免不必要的重复分配。预留空间大于等于字符串的长度。预留空间可以通过capacity()查看。 
- 
resize() 调整字符串的大小。如果字符串长度变小,多余的字符会被截掉。若长度变大,可以设置填充的字符。长度可以通过size()查看。 
上面代码的运行结果:
     
   
根据运行结果来看,可以得到几条结论:
- 
     
 emplace和push的对象是右值的时候
 - emplace函数在容器中直接构造,push不支持直接构造
- push则是先构造一个临时对象,再把该对象拷贝到容器中,临时对象还需要析构
- 针对构造好的右值,emplace和push没有区别
- 
       
 所有针对右值,emplace的效率更高
 
 
- 
     
 emplace和push的对象是左值
 - emplace是直接把构造好的左值对象拷贝到容器当中
- push也是直接把构造好的左值对象拷贝到容器当中
- 
       
 所以针对左值,emplace和push的效率是一样的
 
 
emplace的参数根据元素类型而变化
    
     empalce函数在容器中直接构造元素。传递给emplace函数的参数必须与元素类型的构造函数匹配
    
    。
   
 
版权声明:本文为wangmj_hdu原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
