Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do vector.emplace_back() and vector.push_back() do the same thing?

So I was trying to add integers onto the back of my vector and mistakenly thought push_back() added the new data onto the front of the vector (aka vector[0]). I did a test in Xcode and tested push_back() against emplace_back() and got the same results. I thought they were different, but this makes me think that maybe they do the same thing. If this is so, why does vector have the different methods?

Here's my code in case I was doing:

#include <vector>
#include <iostream> 

using namespace std ;

int main(int argc, const char * argv[])
{
    // for push_back
    vector<int> push;
    push.push_back(1);
    push.push_back(2);
    push.push_back(3);
    push.push_back(4);
    push.push_back(5);
    push.push_back(6);
    //display push_back
    for (int i = 0; i < push.size(); i++) {
        cout << "push[" << i  << "]: " << push[i] << endl;
    }
    // distance between the two funcitons
    cout << endl << endl;

    vector<int> emplace;
    emplace.emplace_back(1);
    emplace.emplace_back(2);
    emplace.emplace_back(3);
    emplace.emplace_back(4);
    emplace.emplace_back(5);
    emplace.emplace_back(6);

    //display emplace_back
    for (int i = 0; i < emplace.size(); i++) {
        cout << "emplace[" << i  << "]: " << emplace[i] << endl;
    }
        return 0;
}

The return was:

push[0]: 1
push[1]: 2
push[2]: 3
push[3]: 4
push[4]: 5
push[5]: 6


emplace[0]: 1
emplace[1]: 2
emplace[2]: 3
emplace[3]: 4
emplace[4]: 5
emplace[5]: 6

I know this is a super easy question, but I just want to make sure I am not doing something stupidly wrong and misunderstanding the abilities of the vector class.

like image 910
Ben Patch Avatar asked Jan 29 '15 19:01

Ben Patch


1 Answers

The difference is that emplace_back will construct the object in place as opposed to copying or moving, cppreference section on std::vector::emplace_back says:

which typically uses placement-new to construct the element in-place at the location provided by the container. The arguments args... are forwarded to the constructor

This matters in the case of heavy objects. We can see that this was the motivation from the original proposal which says:

The motivation for placement insert is that containers—especially node-based containers—are very useful for the storage of heavy objects. In some environments efficiency is very important, but there is in general no way to put elements into containers without copying them. A heavy object may store its data directly, in which case move semantics will not improve copy performance. Furthermore, when efficiency is critical the solution cannot depend on compiler optimizations since they are optional and may not occur where they are most needed. Placement insertion lets us create an element once, in the container where we want it, and never have to move it or copy it. It does so in a simple and direct way by introducing new variadic functions that take arguments that are passed on to the element’s constructor using variadic templates and perfect forwarding.

We can take an example of were this makes a difference from Effective Modern C++ Item 42: Consider emplacement instead of insertion, which has the following example:

std::vector<std::string> vs; // container of std::string
vs.push_back("xyzzy"); // add string literal

which results in the creation of a temporary as opposed to:

vs.emplace_back("xyzzy");

which does not.

like image 157
Shafik Yaghmour Avatar answered Sep 20 '22 05:09

Shafik Yaghmour