Skip to main content
replaced http://stackoverflow.com/ with https://stackoverflow.com/
Source Link
URL Rewriter Bot
URL Rewriter Bot
struct my_pair {
    int foo, bar;
};

Questions:
for [a,b][a,b] I understand the reason for working and not working.
for [c][c], it doesn't work because there is no constructor to forward the arguments to.
for [d][d], why doesn't this work like in the push case?
for [e][e], why does it work when the class name is added?
for [h][h], it seems like this is the most efficient code if there is a constructor that maps the arguments to the members
for [j][j], it seems like this is as bad as a push_back and with extra typing I'm not sure why anyone should do this over push_back
for [k,m][k,m], with the addition of a move constructor it seems like push_back(T&&)push_back(T&&) is being called which results in the same performance as emplace. But again, with the extra typing I'm not sure why anyone would do this.

What is the difference between [d,e][d,e] and why is emplace picky about it. And why does push_back(T&&)push_back(T&&) work without addition of the struct's name?

Should I just stick with push_backpush_back? Is there any reason to use emplace_back(structname{1,2,3})emplace_back(structname{1,2,3}) instead of push_back({1,2,3})push_back({1,2,3}) because it will end up calling push_back(T&&)push_back(T&&) anyway, and is easier to type?

Third, how does emplace_back(arg1,arg2,etc)emplace_back(arg1,arg2,etc), do its magic to avoid the copy or move constructor completely?

struct my_pair {
int foo, bar;
};

Questions:
for [a,b] I understand the reason for working and not working.
for [c], it doesn't work because there is no constructor to forward the arguments to.
for [d], why doesn't this work like in the push case?
for [e], why does it work when the class name is added?
for [h], it seems like this is the most efficient code if there is a constructor that maps the arguments to the members
for [j], it seems like this is as bad as a push_back and with extra typing I'm not sure why anyone should do this over push_back
for [k,m], with the addition of a move constructor it seems like push_back(T&&) is being called which results in the same performance as emplace. But again, with the extra typing I'm not sure why anyone would do this.

What is the difference between [d,e] and why is emplace picky about it. And why does push_back(T&&) work without addition of the struct's name?

Should I just stick with push_back? Is there any reason to use emplace_back(structname{1,2,3}) instead of push_back({1,2,3}) because it will end up calling push_back(T&&) anyway, and is easier to type?

Third, how does emplace_back(arg1,arg2,etc), do its magic to avoid the copy or move constructor completely?

struct my_pair {
    int foo, bar;
};

Questions:
for [a,b] I understand the reason for working and not working.
for [c], it doesn't work because there is no constructor to forward the arguments to.
for [d], why doesn't this work like in the push case?
for [e], why does it work when the class name is added?
for [h], it seems like this is the most efficient code if there is a constructor that maps the arguments to the members
for [j], it seems like this is as bad as a push_back and with extra typing I'm not sure why anyone should do this over push_back
for [k,m], with the addition of a move constructor it seems like push_back(T&&) is being called which results in the same performance as emplace. But again, with the extra typing I'm not sure why anyone would do this.

What is the difference between [d,e] and why is emplace picky about it. And why does push_back(T&&) work without addition of the struct's name?

Should I just stick with push_back? Is there any reason to use emplace_back(structname{1,2,3}) instead of push_back({1,2,3}) because it will end up calling push_back(T&&) anyway, and is easier to type?

Third, how does emplace_back(arg1,arg2,etc), do its magic to avoid the copy or move constructor completely?

Source Link
stewart99
  • 14.6k
  • 7
  • 29
  • 42

c++11 emplace_back and push_back syntax with struct

I'm using MSVC, Visual Studio 2013.

Suppose I have a struct:

struct my_pair {
int foo, bar;
};

And I want to add a bunch of these efficiently, without too creating a temporary and then discarding it:

vector<my_pair> v;
v.push_back(41, 42); // does not work              [a]
v.push_back({41,42}); // works                     [b]
v.emplace_back(41,42); // does not work            [c]
v.emplace_back({41,42}); // does not work          [d]
v.emplace_back(my_pair{41,42}); //works            [e]
       

Now if I add a constructor and copy constructor to my code:

my_pair(int foo_, int bar_) : foo(foo_), bar(bar_) 
{
    cout << "in cstor" << endl;
}
my_pair(const my_pair& copy) : foo(copy.foo), bar(copy.bar)
{
    cout << "in copy cstor" << endl;
}

Then the behavior changes:

v.push_back(41, 42); // does not work                              [f]
v.push_back({41,42}); // displays "in cstor" and "in copy cstor"   [g]
v.emplace_back(41,42); // displays "in cstor"                      [h]
v.emplace_back({41,42}); // does not work                          [i]
v.emplace_back(my_pair{41,42}); // "in cstor" and "in copy cstor"  [j]

If I add a move constructor:

my_pair(my_pair&& move_) : foo(move_.foo), bar(move_.bar)
{
    cout << "in move cstor" << endl;
}

Then:

v.emplace_back(my_pair{41,42}); //displays "in cstor", "in move cstor"   [k]
v.emplace_back({41,42}); // still does not work                          [l]
v.push_back({41,42}); // displays "in cstor", "in move cstor"            [m]

Questions:
for [a,b] I understand the reason for working and not working.
for [c], it doesn't work because there is no constructor to forward the arguments to.
for [d], why doesn't this work like in the push case?
for [e], why does it work when the class name is added?
for [h], it seems like this is the most efficient code if there is a constructor that maps the arguments to the members
for [j], it seems like this is as bad as a push_back and with extra typing I'm not sure why anyone should do this over push_back
for [k,m], with the addition of a move constructor it seems like push_back(T&&) is being called which results in the same performance as emplace. But again, with the extra typing I'm not sure why anyone would do this.

I read that MSVC doesn't add a move constructor for you: Why is copy constructor called in call to std::vector::emplace_back()?

What is the difference between [d,e] and why is emplace picky about it. And why does push_back(T&&) work without addition of the struct's name?

I can only get the full benefits of emplace if I know that there is a constructor that takes each member as argument?

Should I just stick with push_back? Is there any reason to use emplace_back(structname{1,2,3}) instead of push_back({1,2,3}) because it will end up calling push_back(T&&) anyway, and is easier to type?

Third, how does emplace_back(arg1,arg2,etc), do its magic to avoid the copy or move constructor completely?