概述

在C++11中,在引入右值的升级后,调用push_back变的更为高效,原本需要调用构造函数构造这个临时对象,然后调用拷贝构造函数将这个临时对象放入容器中。在C++11升级后,只需要调用构造函数,然后调用移动拷贝函数。

就好比,现在手里有个面包,要把这个放到面包袋子里,原来的逻辑是,生产一个面包,然后在面包袋子里根据生产的面包再复制一个一摸一样的,在引入右值引用升级之后,现在的push_back的逻辑是,生产一个面包,然后把这个面包挪到袋子里(也就是移动拷贝)而不是再照着这个面包复制一个新的。

在此基础上,可以更快些吗?答案是可以的,在C++11中,可以调用emplace_back,emplace_back直接通过参数构造对象至容器中,不需要拷贝或者移动。如果继续使用面包的例子(这里可能不太恰当了),就好比面包生产出来就直接在袋子里了,没有拷贝,没有移动。如此会更加高效。

这是标准库vector的emplace_back方法的介绍以及一些例子:

std::vector<T,Allocator>::emplace_back - cppreference.com

使用

//以下代表功能一样,但效率不一样
vector
emplace <--> insert
emplace_back​ <--> ​push_back 

set
emplcace <--> insert

map
emplace <--> insert

简单的使用,以vectoremplace_back为例

#include <iostream>
#include <vector>

using namespace std;

struct Student {
    string name;
    int age;

    Student(string&& n, int a)
        :name(std::move(n)), age(a)
    {
        cout << "构造" << endl;
    }

    Student(const Student& s)
        : name(std::move(s.name)), age(s.age)
    {
        cout << "拷贝构造" << endl;;
    }

    Student(Student&& s)
        :name(std::move(s.name)), age(s.age)
    {
        cout << "移动构造" << endl;
    }

    Student& operator=(const Student& s);
};

int main()
{
    vector<Student> classes_one;
    vector<Student> classes_two;

    cout << "emplace_back:" << endl;
    classes_one.emplace_back("xiaohong", 24);

    cout << "push_back:" << endl;
    classes_two.push_back(Student("xiaoming", 23));
}

执行结果

原理

push_back():先向容器尾部添加一个右值元素(临时对象),然后调用构造函数构造出这个临时对象,最后调用移动构造函数将这个临时对象放入容器中并释放这个临时对象。
注:最后调用的不是拷贝构造函数,而是移动构造函数。因为需要释放临时对象,所以通过std::move进行移动构造,可以避免不必要的拷贝操作
emplace_back():在容器尾部添加一个元素,调用构造函数原地构造,不需要触发拷贝构造和移动构造。因此比push_back()更加高效。

扩展

验证vector是以2倍增长的(g++)

#include <iostream>
#include <vector>

using namespace std;

struct Student {
    string name;
    int age;

    Student(string&& n, int a)
        :name(std::move(n)), age(a)
    {
        cout << "构造" << endl;
    }

    Student(const Student& s)
        : name(std::move(s.name)), age(s.age)
    {
        cout << "拷贝构造" << endl;;
    }

    Student(Student&& s)
        :name(std::move(s.name)), age(s.age)
    {
        cout << "移动构造" << endl;
    }

    Student& operator=(const Student& s);
};

int main()
{
    vector<Student> classes;
    for(int i=1;i<100;i++) {
        classes.emplace_back("xiaohong", 24);
        cout<<i<<"--"<<classes.capacity();
    }
}

结果

构造
1--1构造
拷贝构造
2--2构造
拷贝构造
拷贝构造
3--4构造
4--4构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
5--8构造
6--8构造
7--8构造
8--8构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
9--16构造
10--16构造
11--16构造
12--16构造
13--16构造
14--16构造
15--16构造
16--16构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
17--32构造
18--32构造
19--32构造
20--32构造
21--32构造
22--32构造
23--32构造
24--32构造
25--32构造
26--32构造
27--32构造
28--32构造
29--32构造
30--32构造
31--32构造
32--32构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
33--64构造
34--64构造
35--64构造
36--64构造
37--64构造
38--64构造
39--64构造
40--64构造
41--64构造
42--64构造
43--64构造
44--64构造
45--64构造
46--64构造
47--64构造
48--64构造
49--64构造
50--64构造
51--64构造
52--64构造
53--64构造
54--64构造
55--64构造
56--64构造
57--64构造
58--64构造
59--64构造
60--64构造
61--64构造
62--64构造
63--64构造
64--64构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
拷贝构造
65--128构造
66--128构造
67--128构造
68--128构造
69--128构造
70--128构造
71--128构造
72--128构造
73--128构造
74--128构造
75--128构造
76--128构造
77--128构造
78--128构造
79--128构造
80--128构造
81--128构造
82--128构造
83--128构造
84--128构造
85--128构造
86--128构造
87--128构造
88--128构造
89--128构造
90--128构造
91--128构造
92--128构造
93--128构造
94--128构造
95--128构造
96--128构造
97--128构造
98--128构造

vs2019结果

construct 
1--1
construct 
copy construct
2--2
construct 
copy construct
copy construct
3--3
construct 
copy construct
copy construct
copy construct
4--4
construct 
copy construct
copy construct
copy construct
copy construct
5--6
construct 
6--6
construct 
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
7--9
construct 
8--9
construct 
9--9
construct 
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
10--13
construct 
11--13
construct 
12--13
construct 
13--13
construct 
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
14--19
construct 
15--19
construct 
16--19
construct 
17--19
construct 
18--19
construct 
19--19
construct 
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
20--28
construct 
21--28
construct 
22--28
construct 
23--28
construct 
24--28
construct 
25--28
construct 
26--28
construct 
27--28
construct 
28--28
construct 
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
29--42
construct 
30--42
construct 
31--42
construct 
32--42
construct 
33--42
construct 
34--42
construct 
35--42
construct 
36--42
construct 
37--42
construct 
38--42
construct 
39--42
construct 
40--42
construct 
41--42
construct 
42--42
construct 
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
43--63
construct 
44--63
construct 
45--63
construct 
46--63
construct 
47--63
construct 
48--63
construct 
49--63
construct 
50--63
construct 
51--63
construct 
52--63
construct 
53--63
construct 
54--63
construct 
55--63
construct 
56--63
construct 
57--63
construct 
58--63
construct 
59--63
construct 
60--63
construct 
61--63
construct 
62--63
construct 
63--63
construct 
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
64--94
construct 
65--94
construct 
66--94
construct 
67--94
construct 
68--94
construct 
69--94
construct 
70--94
construct 
71--94
construct 
72--94
construct 
73--94
construct 
74--94
construct 
75--94
construct 
76--94
construct 
77--94
construct 
78--94
construct 
79--94
construct 
80--94
construct 
81--94
construct 
82--94
construct 
83--94
construct 
84--94
construct 
85--94
construct 
86--94
construct 
87--94
construct 
88--94
construct 
89--94
construct 
90--94
construct 
91--94
construct 
92--94
construct 
93--94
construct 
94--94
construct 
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
copy construct
95--141
construct 
96--141
construct 
97--141
construct 
98--141
construct 
99--141

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐