我是靠谱客的博主 紧张蜻蜓,这篇文章主要介绍C++11容器中新增加的emplace相关函数的使用,现在分享给大家,希望可以做个参考。

C++11中,针对顺序容器(如vector、deque、list),新标准引入了三个新成员:emplace_front、emplace和emplace_back,这些操作构造而不是拷贝元素。这些操作分别对应push_front、insert和push_back,允许我们将元素放置在容器头部、一个指定位置之前或容器尾部。

当调用push或insert成员函数时,我们将元素类型的对象传递给它们,这些对象被拷贝到容器中而当我们调用一个emplace成员函数时,则是将参数传递给元素类型的构造函数。emplace成员使用这些参数在容器管理的内存空间中直接构造元素。

emplace函数的参数根据元素类型而变化,参数必须与元素类型的构造函数相匹配。emplace函数在容器中直接构造元素。传递给emplace函数的参数必须与元素类型的构造函数相匹配。

其它容器中,std::forward_list中的emplace_after、emplace_front函数,std::map/std::multimap中的emplace、emplace_hint函数,std::set/std::multiset中的emplace、emplace_hint,std::stack中的emplace函数,等emplace相似函数操作也均是构造而不是拷贝元素。

emplace相关函数可以减少内存拷贝和移动。当插入rvalue,它节约了一次move构造,当插入lvalue,它节约了一次copy构造。

下面是从其他文章中copy的测试代码,详细内容介绍可以参考对应的reference:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include "emplace.hpp" #include <iostream> #include <vector> #include <string> #include <map> #include <tuple> #include <utility> namespace emplace_ { / // reference: http://www.cplusplus.com/reference/vector/vector/emplace_back/ int test_emplace_1() { { /* template <class... Args> void emplace_back (Args&&... args); */ std::vector<int> myvector = { 10, 20, 30 }; myvector.emplace_back(100); myvector.emplace_back(200); std::cout << "myvector contains:"; for (auto& x : myvector) std::cout << ' ' << x; std::cout << 'n'; } { /* template <class... Args> iterator emplace (const_iterator position, Args&&... args); */ std::vector<int> myvector = { 10, 20, 30 }; auto it = myvector.emplace(myvector.begin() + 1, 100); myvector.emplace(it, 200); myvector.emplace(myvector.end(), 300); std::cout << "myvector contains:"; for (auto& x : myvector) std::cout << ' ' << x; std::cout << 'n'; } return 0; } /// // reference: http://en.cppreference.com/w/cpp/container/vector/emplace_back namespace { struct President { std::string name; std::string country; int year; President(std::string p_name, std::string p_country, int p_year) : name(std::move(p_name)), country(std::move(p_country)), year(p_year) { std::cout << "I am being constructed.n"; } President(President&& other) : name(std::move(other.name)), country(std::move(other.country)), year(other.year) { std::cout << "I am being moved.n"; } President& operator=(const President& other) = default; }; } int test_emplace_2() { /* The following code uses emplace_back to append an object of type President to a std::vector. It demonstrates how emplace_back forwards parameters to the President constructor and shows how using emplace_back avoids the extra copy or move operation required when using push_back. */ std::vector<President> elections; std::cout << "emplace_back:n"; elections.emplace_back("Nelson Mandela", "South Africa", 1994); std::vector<President> reElections; std::cout << "npush_back:n"; reElections.push_back(President("Franklin Delano Roosevelt", "the USA", 1936)); std::cout << "nContents:n"; for (President const& president : elections) { std::cout << president.name << " was elected president of " << president.country << " in " << president.year << ".n"; } for (President const& president : reElections) { std::cout << president.name << " was re-elected president of " << president.country << " in " << president.year << ".n"; } return 0; } // reference: https://stackoverflow.com/questions/4303513/push-back-vs-emplace-back int test_emplace_3() { /* template <class... Args> pair<iterator,bool> emplace (Args&&... args); */ typedef std::tuple<int, double, std::string> Complicated; std::map<int, Complicated> m; int anInt = 4; double aDouble = 5.0; std::string aString = "C++"; // cross your finger so that the optimizer is really good //m.insert(/*std::make_pair*/std::pair<int, Complicated>(4, Complicated(anInt, aDouble, aString))); m.insert(std::make_pair(4, Complicated(anInt, aDouble, aString))); // should be easier for the optimizer m.emplace(6, Complicated(anInt, aDouble, aString)); /* std::piecewise_construct: This constant value is passed as the first argument to construct a pair object to select the constructor form that constructs its members in place by forwarding the elements of two tuple objects to their respective constructor. */ m.emplace(std::piecewise_construct, std::make_tuple(8), std::make_tuple(anInt, aDouble, aString)); return 0; } // // reference: https://corecplusplustutorial.com/difference-between-emplace_back-and-push_back-function/ namespace { class Dat { int i; std::string ss; char c; public: Dat(int ii, std::string s, char cc) :i(ii), ss(s), c(cc) { } ~Dat() { } }; } int test_emplace_4() { std::vector<Dat> vec; vec.reserve(3); vec.push_back(Dat(89, "New", 'G')); // efficiency lesser //vec.push_back(678, "Newer", 'O'); // error,push_back can’t accept three arguments vec.emplace_back(890, "Newest", 'D'); // work fine, efficiency is also more return 0; } } // namespace emplace_

GitHub: https://github.com/fengbingchun/Messy_Test  

最后

以上就是紧张蜻蜓最近收集整理的关于C++11容器中新增加的emplace相关函数的使用的全部内容,更多相关C++11容器中新增加内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(44)

评论列表共有 0 条评论

立即
投稿
返回
顶部