STL vector添加元素push_back()和emplace_back()的区别
来源:C 语言中文网——C++ STL vector添加元素详解
底层实现的区别
emplace_back()
函数是 C++ 11
新增加的,其功能和 push_back()
相同,都是在 vector
容器的尾部添加一个元素。
emplace_back()
和 push_back()
的区别,就在于底层实现的机制不同。
push_back()
向容器尾部添加元素时,首先会创建这个元素,然后再将这个元素拷贝或者移动到容器中(如果是拷贝的话,事后会自行销毁先前创建的这个元素)。- 而
emplace_back()
在实现时,则是直接在容器尾部创建这个元素,省去了拷贝或移动元素的过程。
为了让大家清楚的了解它们之间的区别,我们创建一个包含类对象的 vector
容器,如下所示:
#include <vector>
#include <iostream>
using namespace std;
class testDemo
{
public:
testDemo(int num):num(num){
std::cout << "调用构造函数" << endl;
}
testDemo(const testDemo& other) :num(other.num) {
std::cout << "调用拷贝构造函数" << endl;
}
testDemo(testDemo&& other) :num(other.num) {
std::cout << "调用移动构造函数" << endl;
}
private:
int num;
};
int main()
{
cout << "emplace_back:" << endl;
std::vector<testDemo> demo1;
demo1.emplace_back(2);
cout << "push_back:" << endl;
std::vector<testDemo> demo2;
demo2.push_back(2);
}
运行结果为:
emplace_back:
调用构造函数
push_back:
调用构造函数
调用移动构造函数
在此基础上,读者可尝试将 testDemo
类中的移动构造函数注释掉,再运行程序会发现,运行结果变为:
emplace_back:
调用构造函数
push_back:
调用构造函数
调用拷贝构造函数
由此可以看出,push_back()
在底层实现时,会优先选择调用移动构造函数,如果没有才会调用拷贝构造函数。
显然完成同样的操作,push_back()
的底层实现过程比 emplace_back()
更繁琐,换句话说,emplace_back()
的执行效率比 push_back()
高。因此,在实际使用时,建议大家优先选用 emplace_back()
。
由于emplace_back()
是 C++ 11 标准新增加的,如果程序要兼顾之前的版本,还是应该使用push_back()
。
添加pair<type, type>
类型元素区别
vector<pair<int, int> > v;
v.push_back({1, 2});
v.emplace_back(1, 2);
添加结构体struct
类型元素区别
#include <bits/stdc++.h>
using namespace std;
struct NODE {
string name;
int score1, score2;
NODE() { }
NODE(string _name, int _score1, int _score2) : name(_name), score1(_score1), score2(_score2) { }
};
int main()
{
vector<NODE> data;
data.emplace_back("a", 1, 3);
data.push_back({"b", 2, 4});
for (auto &a : data) {
cout << a.name << " " << a.score1 << " " << a.score2 << endl;
}
return 0;
}
附:pair
排序函数写法
bool cmp (const pair<string, int> &p1, const pair<string, int> &p2) {
return p1.second == p2.second ? p1.first < p2.first : p1.second > p2.second;
}