emplace_back能直接通过参数构造对象,避免了内存的拷贝,相比push_back性能有提升。大多数情况下,应优先使用emplace_back代替push_back。
标准库容器(array除外,长度不可改变,不能插入元素)都增加了类似方法:emplace,emplace_hint,emplace_front,emplace_after和emplace_back等。
vector的emplace_back的基本用法:
#include <vector>
#include <iostream>
using namespace std;
struct A
{
int x;
double y;
A(int a, double b):x(a),y(b) {}
};
int main() {
vector<A> v;
v.emplace_back(1, 2);
cout << v.size() << endl;
return 0;
}
需要有对应的构造函数,如果没有对应的构造函数,编译器会报错。
emplace_back和push_back的比较:
#include <vector>
#include <map>
#include <string>
#include <iostream>
using namespace std;
struct Complicated
{
int year;
double country;
std::string name;
// 对应的构造函数
Complicated(int a, double b, string c):year(a),country(b),name(c)
{
cout << "is constructed" << endl;
}
// "拷贝"构造函数
Complicated(const Complicated& other):year(other.year),country(other.country),name(std::move(other.name))
// std::move()将左值变为右值引用,应用move语义调用构造函数,避免了拷贝
{
cout << "is moved" << endl;
}
};
int main() {
std::map<int, Complicated> m;
int anInt = 4;
double aDouble = 5.0;
std::string aString = "C++";
cout << "insert:" << endl;
m.insert(std::make_pair(1, Complicated(anInt, aDouble, aString)));
cout << "emplace" << endl;
m.emplace(4, Complicated(anInt, aDouble, aString));
cout << "emplace_back:" << endl;
vector<Complicated> v;
v.emplace_back(anInt, aDouble, aString);
cout << "push_back:" << endl;
v.push_back(Complicated(anInt, aDouble, aString));
return 0;
}
输出:
insert:
is constructed
is moved
is moved
emplace:
is constructed
is moved
emplace_back:
is constructed
push_back:
is constructed
is moved
is moved
可以看出,emplace/emplace_back的性能比insert/push_back的性能提高很多。注意,不能完全用emplace_back代替push_back,前提是要有对应的构造函数。