Similar questions exist here and here but I think we haven't got a clear answer.
The C++11 standard has two ways to add a new element to the end of a vector: std::vector::push_back
and std::vector::emplace_back
.
The difference between them is the std::vector::emplace_back
constructs the object in place and std::vector::push_back
basically copies the object (or primitive type) or moves it to the end of vector.
Then, std::vector::push_back
looks like the better option to add primitive types into a std::vector
. For example:
std::vector<int> vVec;
vVec.push_back(10);
int iVar = 30;
vVec.push_back(iVar);
But it is not so clear to me when we talk about non-primitive types. Let's take a vector of std::string
for example. If I want to add a literal string I shall use std::vector::emplace_back
and when I want to copy or move a string object I shall use std::vector::push_back
?
To make it clearer what I'm asking, let's see a few scenarios:
1st scenario:
std::vector<string> vVec;
std::string sTest("1st scenario");
vVec.push_back(sTest);
vVec.emplace_back(sTest);
push_back
makes a copy of sTest
as a new element at the end of vVec
meanwhile emplace_back
creates the string object an the end of vVec
and copies the content of sTest
into it.
Which one is more efficient in this case? Or doesn't it matter?
2nd scenario:
std::vector<string> vVec;
std::string sTest1("2st scenario");
std::string sTest2("2st scenario");
vVec.push_back(move(sTest1));
vVec.emplace_back(move(sTest2));
push_back
is ready for move semantics, but what happens with emplace_back
? Which one is more efficient in this case?
3rd scenario:
std::vector<string> vVec;
std::string sTest("3st scenario");
vVec.push_back(sTest.substr(4,4));
vVec.emplace_back(sTest.substr(4,4));
Because std::string::substr
returns another std::string
we have the same situation as in the 2nd scenario?
If std::vector::emplace_back
is more efficient than std::vector::push_back
only when literals are involved (in place construction), is its use really justified? If it is, can you give me some examples?
Important to note that std::vector::emplace_back
was implemented in C++11 not in C++0x then I suppose there is a good reason for it to exists.
I take a while to really understand what the advantage to use std::vector::emplace as aschepler said.
I found out the better scenario to use that is when we have our own class that receive some data when it is construct.
To make more clear, let's suppose we have:
Then we can have a line like this:
vVec.emplace(get1stElem(), get2ndElem(), get3rdElem());
Then the std::vector::emplace will construct MyObject in place more efficiently than std::vector::push_back.