- 两个函数都是向容器末端插入元素
- emplace_back()直接构造数据插入
- push_back()需要先构造数据,再将该数据拷贝或者移动到容器中。
因为 push_back 的步骤比 emplace_back 的实现繁琐,所以应该尽量使用 emplace_back()。但实际上,emplace_back 是需要条件的,如下:
#include <iostream>
#include <vector>
using namespace std;
struct Args{
int x, y;
string name;
double len;
};
void print(const vector<Args>& data) {
for (const auto& e : data) {
cout << e.x << ' ' << e.y << ' ' << e.name << ' ' << e.len << endl;
}
}
int main() {
cout << "push_back\n";
vector<Args> a1;
a1.push_back({1, 1, "a11"});
a1.push_back({1, 2, "a12", 4});
print(a1);
cout << "emplace_back\n";
vector<Args> a2;
a2.emplace_back(2, 1, "a21");
a2.emplace_back(2, 2, "a22", 4);
print(a2);
return 0;
}
其中,27 行 28 行直接使用 emplace_back()会报错,提示没有构造器
因此准备为它加上构造器,但是,当加上构造器后,会发现还是存在问题,原因是,参数不匹配的问题,如下
struct Args{
int x, y;
string name;
double len;
Args(int x, int y, string name, double len):x(x), y(y), name(name), len(len){}
};
而且会发现,加上构造器后,不仅 emplace_back 会有问题,push_back 参数不够也会存在问题。
因此,还需要提供三个参数的构造器。
更改后可以正常运行
#include <iostream>
#include <vector>
using namespace std;
struct Args{
int x, y;
string name;
double len;
Args(int x, int y, string name) : x(x), y(y), name(name) {
this->len = 3;
}
Args(int x, int y, string name, double len):x(x), y(y), name(name), len(len){}
};
void print(const vector<Args>& data) {
for (const auto& e : data) {
cout << e.x << ' ' << e.y << ' ' << e.name << ' ' << e.len << endl;
}
}
int main() {
cout << "push_back\n";
vector<Args> a1;
a1.push_back({1, 1, "a11"});
a1.push_back({1, 2, "a12", 4});
print(a1);
cout << "emplace_back\n";
vector<Args> a2;
a2.emplace_back(2, 1, "a21");
a2.emplace_back(2, 2, "a22", 4);
print(a2);
return 0;
}
/*
push_back
1 1 a11 3
1 2 a12 4
emplace_back
2 1 a21 3
2 2 a22 4
*/
同时发现,当正确提供构造器后,CLion 会提示使用 emplace_back()代替 push_back();
由此可见:
- push_back 方便我们在书写结构体或者类的时候偷懒,我们可以不提供构造器,在 push_back 的时候,按照元素的声明顺序给参数即可,push_back 内部会帮我们处理构造器问题。但是 emplace_back 必须我们自己提供构造器。
- 当正确提供构造器后,推荐使用 emplace_back,因为这样可以提高效率。
参考资料:【C++11】之 emplace_back() 与 push_back() 的区别_emplace_back和push back的区别-优快云博客