- C++11标准以后,给STL标准库的每一个容器(基本的线性容器:vector,list,deque,关联容器:set,map)的push和insert方法,都匹配了emplace的新的方法,也是用来添加数据的。
- insert对应emplace;
- push_back对应emplace_back;
- push_front对应emplace_front;
emplace使用的时候感觉和之前的功能是一样的,都是添加新的元素,但是到底有什么不同呢?
例1—传入左值对象
#include<iostream>
#include<vector>
using namespace std;
class Test
{
public:
Test(int a) { cout << "Test(int)" << endl; }
Test(int a, int b) { cout << "Test(int,int)" << endl; }
Test(const Test& a) { cout << "Test(const Test&)" << endl; }
Test(const Test&& a) { cout << "Test(const Test&&)" << endl; }
~Test() { cout << "~Test()" << endl; }
};
int main()
{
Test t1(10);// 左值
vector<Test>v;
v.reserve(100);//只开辟空间,没有构建对象
cout << "=====================" << endl;
v.push_back(t1);//匹配的是带左值引用参数的拷贝构造函数
v.emplace_back(t1);//匹配的是带左值引用参数的拷贝构造函数
cout << "=====================" << endl;
return 0;
}
如果是直接插入 已存在的 是左值的 对象,两个方法是没有区别的,都是调用带左值引用参数的拷贝构造函数构建vector上的对象。
例2—传入临时对象
#include<iostream>
#include<vector>
using namespace std;
class Test
{
public:
Test(int a) { cout << "Test(int)" << endl; }
Test(int a, int b) { cout << "Test(int,int)" << endl; }
Test(const Test& a) { cout << "Test(const Test&)" << endl; }
Test(const Test&& a) { cout << "Test(const Test&&)" << endl; }
~Test() { cout << "~Test()" << endl; }
};
int main()
{
Test t1(10);//是左值哦
vector<Test>v;
v.reserve(100);//只开辟空间,没有构建对象
cout << "=====================" << endl;
v.push_back(Test(20));//匹配的是带右值引用参数的拷贝构造函数
v.emplace_back(Test(20));//匹配的是带右值引用参数的拷贝构造函数
cout << "=====================" << endl;
return 0;
}
- 用临时对象在vector底层构造新对象时 ,匹配了右值引用的拷贝构造函数;
- 临时对象的生命周期很短,只存在当前语句中。
都是生成临时对象,然后调用带右值引用参数的拷贝构造函数构建vector上的对象
这两种方法还是没有区别啊!
只要是插入对象,这2种方法是没有区别的!!!
例3—传入你要构建Test对象所需要的参数
-
现在相当于是实参在传递的过程中,没有定义过对象,没有生成过临时对象!!!
-
直接传入你要构建Test对象所需要的参数(构造函数的参数),然后直接在vector底层调用了相应的构造函数—在vector底层直接构造Test对象了。
-
这样做,当然好,效率直接就提升了啊!
例4—map中传入要构造对象的参数
int main()
{
unordered_map<int, string>map;
map.insert(make_pair(10, "linzeyu"));
//构建临时对象,然后拿临时对象调用右值引用参数的拷贝构造函数构造map上的对象
//在map底层构建好对象后,出了这条语句,临时对象析构。
map.emplace(10, "zhang san");
//直接传入构建对象所需要的参数,在map底层直接调用普通构造函数生成对象了,
//没有产生临时对象等额外的对象,没有额外的函数的调用
return 0;
}