C++ 开发中我们会经常用到插入操作对STL的各种容器进行操作,比如vector,map,set等。在引入右值引用,移动构造函数,移动赋值运算符之前,通常使用push_back()向容器中加入一个右值元素(临时对象)时,首先会调用构造函数构造这个临时对象,然后需要调用拷贝构造函数将这个临时对象放入容器中,原来的临时变量释放,这样造成的问题就是临时变量申请资源的浪费(先调用构造函数,再调用拷贝构造函数)。
引入了右值引用,移动构造函数后,push_back()右值时就会调用构造函数和移动构造函数,在插入的时候可以直接构造 (先调用构造函数,再调用移动构造函数) 。
C++11标准引入了emplace。Vector有俩个函数可以使用:emplace, emplace_back。 emplace类似于insert,emplace_back类似于push_back。
emplace_back
函数原型:
template <class... Args>
void emplace_back (Args&&... args);
在容器尾部添加一个元素,这个元素原地构造,不需要触发拷贝构造函数和移动构造函数。
使用push_back
#include <vector>
struct A{
A(int a, int b){
std::cout << "\nconstructor" << std::endl;
}
/*
A(const A&){
std::cout << "\n copy constructor" << std::endl;
}*/
A(A&&){
std::cout << "\nmove" << std::endl;
}
};
int main(){
std::vector<A> vec;
vec.push_back(A(1,2));
}
输出:
constructor
move
使用emplace_back
#include <vector>
struct A{
A(int a, int b){
std::cout << "\nconstructor" << std::endl;
}
/*
A(const A&){
std::cout << "\n copy constructor" << std::endl;
}*/
A(A&&){
std::cout << "\nmove" << std::endl;
}
};
int main(){
std::vector<A> vec;
vec.emplace_back(1,2);
}
输出:
constructor