-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
003_stl_emplace.cpp
160 lines (132 loc) · 4.06 KB
/
003_stl_emplace.cpp
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#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;
}
}