12

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.

Bryan Chen
  • 45,816
  • 18
  • 112
  • 143
Ben Patch
  • 1,213
  • 1
  • 9
  • 12
  • 2
    @nawaz That duplicate is not a very good one, it is about a visual studio non-compliance and does not really answer this question. – Shafik Yaghmour Jan 29 '15 at 19:20
  • 2
    `push_back` uses copy/move constructors, `emplace_back` constructs in place. I believe `emplace_back` is a superset of `push_back`, since you can use copy/move constructors with in-place construction. – Suedocode Jan 29 '15 at 20:33
  • @Aggieboy: Yes, it is. And if it was designed today, we probably would only have `emplace_back`. – Deduplicator Jan 29 '15 at 20:51
  • @ShafikYaghmour: That's what it mentions prominently. But one can simply ignore that extra information. – Deduplicator Jan 29 '15 at 20:53
  • @Deduplicator I still don't think it really answers this question, perhaps in a tangential way but is that really a duplicate then, sounds pretty lazy to me. – Shafik Yaghmour Jan 29 '15 at 20:54
  • @ShafikYaghmour: Well, if there's a dupe you like better, don't hesitate to open and re-close. – Deduplicator Jan 29 '15 at 21:21
  • 1
    @Deduplicator actually I can not find a good duplicate, which means it is probably a good question. I was pretty surprised I expected to find an exact duplicate pretty quickly, otherwise I would have reopened and reclosed already. There may be an exact duplicate out there someplace but If I can't find it after a few minutes then most people searching online for this topic probably can't either. – Shafik Yaghmour Jan 29 '15 at 21:23
  • 1
    The supposed dupe simply can't include a satisfactory answer to this question. – Oktalist Jan 29 '15 at 21:35

1 Answers1

12

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.

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
  • `vector::push_back` typically uses placement new also. – M.M Jan 30 '15 at 05:35
  • 7
    It should perhaps be mentioned (since the OP asked this), that `push_back` and `emplace_back` are exactly the same in the case where we already have an existing object that we want to copy/move into the vector; they are only different when we are simultaneously constructing and pushing, as in your example. – M.M Jan 30 '15 at 05:37