C++

来源: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;
}
This is just a placeholder img.