Moving an object into a map - c++

The problem with this is that the huge objects will be copied into the maps
Huge huge1(some,args);
Huge huge2(some,args);
std::map<int,Huge> map1;
std::map<Huge,int> map2;
map1.insert({0,huge1});
map2.insert({huge2,0});
how can I guarantee a move? Will this work or is there more to it?
map1.insert({0,std::move(huge1)});
map2.insert({std::move(huge2),0});

std::map::insert has an overload for R-values:
std::pair<iterator,bool> insert(value_type&&);
Any expression which binds to this overload will invoke R-value constructors. Since std::map<K,V>::value_type is std::pair<const key_type, mapped_type>, and std::pair has a constructor that takes R-values:
template<class U1, class U2>
pair(U1&& x, U2&& y);
then you are guaranteed that R-value constructors for key_type and mapped_type will be invoked, both in the creation of the pair object, and in the map insertion, as long as you insert the pair using an expression that creates R-values, such as:
map1.insert(std::make_pair(0, Huge());
OR
map1.insert(std::make_pair(0, std::move(huge1));
Of course, all of this is dependent on Huge having a proper R-value constructor:
Huge(Huge&& h)
{
...
}
Finally, you can also use std::map::emplace if you simply want to construct a new Huge object as an element in the map.

You could do that (the {0,std::move(huge1)} part). But you could also skip the middleman (assuming you're constructing the objects within the function) like this:
map1.emplace(std::piecewise_construct, 0, std::forward_as_tuple(some, args));
map2.emplace(std::piecewise_construct, std::forward_as_tuple(some, args), 0);
Or, if your function is given the objects, you can still use emplace:
map1.emplace(0, std::move(huge1));
map2.emplace(std::move(huge1), 0);

An alternative that avoids both copying and moving would be to use std::map::emplace(). From the linked reference page:
Inserts a new element to the container. The element is constructed in-place, i.e. no copy or move operations are performed. The constructor of the element type (value_type, that is, std::pair) is called with exactly the same arguments as supplied to the function, forwarded with std::forward(args)....

Along with the above, you can also rely on std::unique_ptr<>'s lack of a copy constructor, though this changes the interface slightly.
#include <iostream>
#include <map>
#include <memory>
class Huge {
public:
Huge(int i) : x{i} {}
int x;
};
using HugePtrT = std::unique_ptr<Huge>;
using MyMapT = std::map<int, HugePtrT>;
int
main() {
MyMapT myMap;
myMap[42].reset(new Huge{1});
std::cout << myMap[42]->x << std::endl;
myMap[43] = std::move(myMap[42]);
if (myMap[42])
std::cout << "42: " << myMap[42]->x << std::endl;
if (myMap[43])
std::cout << "43: " << myMap[43]->x << std::endl;
}
which produces the expected output:
1
43: 1
If you omit the std::move() call, the program will fail to compile. Similarly, you could use .reset() to assign the pointer.
This has the advantage that it will work on classes that don't have an R-value constructor, is very light weight, memory ownership is clearly defined, and gives you a boost::optional<>-like semantics. An argument could be made that std::unique_ptr is lighter weight than an object that has been moved via an R-value constructor because an R-Value moved object requires an allocation (though to be fair, all of the C++11 compilers that I'm aware of support Return Value Optimizations or copy elision), even though the guts of the object are moved.
The reason std::unique_ptr<> works like this is because std::unique_ptr<> does not have a copy constructor, it only has a move constructor.

Related

Difference between vector::push_back(Foo()) and vector::emplace_back(Foo())? [duplicate]

I'm a bit confused regarding the difference between push_back and emplace_back.
void emplace_back(Type&& _Val);
void push_back(const Type& _Val);
void push_back(Type&& _Val);
As there is a push_back overload taking a rvalue reference I don't quite see what the purpose of emplace_back becomes?
In addition to what visitor said :
The function void emplace_back(Type&& _Val) provided by MSCV10 is non conforming and redundant, because as you noted it is strictly equivalent to push_back(Type&& _Val).
But the real C++0x form of emplace_back is really useful: void emplace_back(Args&&...);
Instead of taking a value_type it takes a variadic list of arguments, so that means that you can now perfectly forward the arguments and construct directly an object into a container without a temporary at all.
That's useful because no matter how much cleverness RVO and move semantic bring to the table there is still complicated cases where a push_back is likely to make unnecessary copies (or move). For example, with the traditional insert() function of a std::map, you have to create a temporary, which will then be copied into a std::pair<Key, Value>, which will then be copied into the map :
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(4, Complicated(anInt, aDouble, aString)));
// should be easier for the optimizer
m.emplace(4, anInt, aDouble, aString);
So why didn't they implement the right version of emplace_back in MSVC? Actually, it bugged me too a while ago, so I asked the same question on the Visual C++ blog. Here is the answer from Stephan T Lavavej, the official maintainer of the Visual C++ standard library implementation at Microsoft.
Q: Are beta 2 emplace functions just some kind of placeholder right now?
A: As you may know, variadic templates
aren't implemented in VC10. We
simulate them with preprocessor
machinery for things like
make_shared<T>(), tuple, and the new
things in <functional>. This
preprocessor machinery is relatively
difficult to use and maintain. Also,
it significantly affects compilation
speed, as we have to repeatedly
include subheaders. Due to a
combination of our time constraints
and compilation speed concerns, we
haven't simulated variadic templates
in our emplace functions.
When variadic templates are
implemented in the compiler, you can
expect that we'll take advantage of
them in the libraries, including in
our emplace functions. We take
conformance very seriously, but
unfortunately, we can't do everything
all at once.
It's an understandable decision. Everyone who tried just once to emulate variadic template with preprocessor horrible tricks knows how disgusting this stuff gets.
emplace_back shouldn't take an argument of type vector::value_type, but instead variadic arguments that are forwarded to the constructor of the appended item.
template <class... Args> void emplace_back(Args&&... args);
It is possible to pass a value_type which will be forwarded to the copy constructor.
Because it forwards the arguments, this means that if you don't have rvalue, this still means that the container will store a "copied" copy, not a moved copy.
std::vector<std::string> vec;
vec.emplace_back(std::string("Hello")); // moves
std::string s;
vec.emplace_back(s); //copies
But the above should be identical to what push_back does. It is probably rather meant for use cases like:
std::vector<std::pair<std::string, std::string> > vec;
vec.emplace_back(std::string("Hello"), std::string("world"));
// should end up invoking this constructor:
//template<class U, class V> pair(U&& x, V&& y);
//without making any copies of the strings
Optimization for emplace_back can be demonstrated in next example.
For emplace_back constructor A (int x_arg) will be called. And for
push_back A (int x_arg) is called first and move A (A &&rhs) is called afterwards.
Of course, the constructor has to be marked as explicit, but for current example is good to remove explicitness.
#include <iostream>
#include <vector>
class A
{
public:
A (int x_arg) : x (x_arg) { std::cout << "A (x_arg)\n"; }
A () { x = 0; std::cout << "A ()\n"; }
A (const A &rhs) noexcept { x = rhs.x; std::cout << "A (A &)\n"; }
A (A &&rhs) noexcept { x = rhs.x; std::cout << "A (A &&)\n"; }
private:
int x;
};
int main ()
{
{
std::vector<A> a;
std::cout << "call emplace_back:\n";
a.emplace_back (0);
}
{
std::vector<A> a;
std::cout << "call push_back:\n";
a.push_back (1);
}
return 0;
}
output:
call emplace_back:
A (x_arg)
call push_back:
A (x_arg)
A (A &&)
One more example for lists:
// constructs the elements in place.
emplace_back("element");
// creates a new object and then copies (or moves) that object.
push_back(ExplicitDataType{"element"});
Specific use case for emplace_back: If you need to create a temporary object which will then be pushed into a container, use emplace_back instead of push_back. It will create the object in-place within the container.
Notes:
push_back in the above case will create a temporary object and move it
into the container. However, in-place construction used for emplace_back would be more
performant than constructing and then moving the object (which generally involves some copying).
In general, you can use emplace_back instead of push_back in all the cases without much issue. (See exceptions)
A nice code for the push_back and emplace_back is shown here.
http://en.cppreference.com/w/cpp/container/vector/emplace_back
You can see the move operation on push_back and not on emplace_back.
emplace_back conforming implementation will forward arguments to the vector<Object>::value_typeconstructor when added to the vector. I recall Visual Studio didn't support variadic templates, but with variadic templates will be supported in Visual Studio 2013 RC, so I guess a conforming signature will be added.
With emplace_back, if you forward the arguments directly to vector<Object>::value_type constructor, you don't need a type to be movable or copyable for emplace_back function, strictly speaking. In the vector<NonCopyableNonMovableObject> case, this is not useful, since vector<Object>::value_type needs a copyable or movable type to grow.
But note that this could be useful for std::map<Key, NonCopyableNonMovableObject>, since once you allocate an entry in the map, it doesn't need to be moved or copied ever anymore, unlike with vector, meaning that you can use std::map effectively with a mapped type that is neither copyable nor movable.

C++ std::vector difference between creating object then adding it vs creating it inside the vector?

Since std::vector::push_back(obj) creates a copy of the object, would it be more efficient to create it within the push_back() call than beforehand?
struct foo {
int val;
std::string str;
foo(int _val, std::string _str) :
val(_val), str(_str) {}
};
int main() {
std::vector<foo> list;
std::string str("hi");
int val = 2;
list.push_back(foo(val,str));
return 0;
}
// or
int main() {
std::vector<foo> list;
std::string str("hi");
int val = 2;
foo f(val,str);
list.push_back(f);
return 0;
}
list.push_back(foo(val,str));
asks for a foo object to be constructed, and then passed into the vector. So both approaches are similar in that regard.
However—with this approach a c++11 compiler will treat the foo object as a "temporary" value (rvalue) and will use the void vector::push_back(T&&) function instead of the void vector::push_back(const T&) one, and that's indeed to be faster in most situations. You could also get this behavior with a previously declared object with:
foo f(val,str);
list.push_back(std::move(f));
Also, note that (in c++11) you can do directly:
list.emplace_back(val, str);
It's actually somewhat involved. For starters, we should note that std::vector::push_back is overloaded on the two reference types:
void push_back( const T& value );
void push_back( T&& value );
The first overload is invoked when we pass an lvalue to push_back, because only an lvalue reference type can bind to an lvalue, like f in your second version. And in the same fashion, only an rvalue reference can bind to an rvalue like in your first version.
Does it make a difference? Only if your type benefits from move semantics. You didn't provide any copy or move operation, so the compiler is going to implicitly define them for you. And they are going to copy/move each member respectively. Because std::string (of which you have a member) actually does benefit from being moved if the string is very long, you might see better performance if you choose not to create a named object and instead pass an rvalue.
But if your type doesn't benefit from move semantics, you'll see no difference whatsoever. So on the whole, it's safe to say that you lose nothing, and can gain plenty by "creating the object at the call".
Having said all that, we mustn't forget that a vector supports another insertion method. You can forward the arguments for foo's constructor directly into the vector via a call to std::vector::emplace_back. That one will avoid any intermediate foo objects, even the temporary in the call to push_back, and will create the target foo directly at the storage the vector intends to provide for it. So emplace_back may often be the best choice.
You ‘d better use
emplace_back(foo(val,str))
if you are about creating and pushing new element to your vector. So you perform an in-place construction.
If you’ve already created your object and you are sure you will never use it alone for another instruction, then you can do
push_back(std::move(f))
In that case your f object is dangled and his content is owned by your vector.

Are there any cases where it is incorrect to replace push_back with emplace_back?

Can I break a valid C++03 program by replacing std::vector::push_back with emplace_back and compiling it with C++ 11 compiler? From reading emplace_back reference I gather it shouldn't happen, but I'll admit I don't fully get rvalue references.
I constructed a short example that actually fails to compile when push_back is replaced by emplace_back:
#include <vector>
struct S {
S(double) {}
private:
explicit S(int) {}
};
int main() {
std::vector<S>().push_back(0); // OK
std::vector<S>().emplace_back(0); // error!
}
The call to push_back needs to convert its argument 0 from type int to type S. Since this is an implicit conversion, the explicit constructor S::S(int) is not considered, and S::S(double) is called. On the other hand, emplace_back performs direct initialization, so both S::S(double) and S::S(int) are considered. The latter is a better match, but it's private, so the program is ill-formed.
Yes, you can change the behavior (more than just avoiding a copy constructor call), since emplace_back only sees imperfectly forwarded arguments.
#include <iostream>
#include <vector>
using namespace std;
struct Arg { Arg( int ) {} };
struct S
{
S( Arg ) { cout << "S(int)" << endl; }
S( void* ) { cout << "S(void*)" << endl; }
};
auto main()
-> int
{
vector<S>().ADD( 0 );
}
Example builds:
[H:\dev\test\0011]
> g++ foo.cpp -D ADD=emplace_back && a
S(int)
[H:\dev\test\0011]
> g++ foo.cpp -D ADD=push_back && a
S(void*)
[H:\dev\test\0011]
> _
Addendum: as pointed out by Brian Bi in his answer, another difference that can lead to different behavior is that a push_back call involves an implicit conversion to T, which disregards explicit constructors and conversion operators, while emplace_back uses direct initialization, which does consider also explicit constructors and conversion operators.
The emplace versions don't create an object of the desired type at all under exception circumstances. This can lead to a bug.
Consider the following example, which uses std::vector for simplicity (assume uptr behaves like std::unique_ptr, except the constructor is not explicit):
std::vector<uptr<T>> vec;
vec.push_back(new T());
It is exception-safe. A temporary uptr<T> is created to pass to push_back, which is moved into the vector. If reallocation of the vector fails, the allocated T is still owned by a smart pointer which correctly deletes it.
Compare to:
std::vector<uptr<T>> vec;
vec.emplace_back(new T());
emplace_back is not allowed to create a temporary object. The ptr will be created once, in-place in the vector. If reallocation fails, there is no location for in-place creation, and no smart pointer will ever be created. The T will be leaked.
Of course, the best alternative is:
std::vector<std::unique_ptr<T>> vec;
vec.push_back(make_unique<T>());
which is equivalent to the first, but makes the smart pointer creation explicit.
If you don't have crazy side-effects in copy constructor of the objects that you hold in your vector, then no.
emplace_back was introduced to optimise-out unnecessary copying and moving.
Suppose a user-defined class could be initialized from braced-initializer. e.g.
struct S {
int value;
};
then
std::vector<S> v;
v.push_back({0}); // fine
v.emplace_back({0}); // template type deduction fails
std::vector::emplace_back is template function but std::vector::push_back is non-template function. With a braced-initializer std::vector::emplace_back would fail because template argument deduction fails.
Non-deduced contexts
6) The parameter P, whose A is a braced-init-list, but P is not std::initializer_list or a reference to one:
LIVE
int main() {
std::vector<S>().push_back(0);
std::vector<S>().emplace_back(0);
}
Give struct constructor in emplace_back i.e The above code will be like this
int main() {
std::vector<S>().push_back(0);
std::vector<S>().emplace_back(S(0));
}

Difference between push_back and emplace_back in the case of a temporary value [duplicate]

I'm a bit confused regarding the difference between push_back and emplace_back.
void emplace_back(Type&& _Val);
void push_back(const Type& _Val);
void push_back(Type&& _Val);
As there is a push_back overload taking a rvalue reference I don't quite see what the purpose of emplace_back becomes?
In addition to what visitor said :
The function void emplace_back(Type&& _Val) provided by MSCV10 is non conforming and redundant, because as you noted it is strictly equivalent to push_back(Type&& _Val).
But the real C++0x form of emplace_back is really useful: void emplace_back(Args&&...);
Instead of taking a value_type it takes a variadic list of arguments, so that means that you can now perfectly forward the arguments and construct directly an object into a container without a temporary at all.
That's useful because no matter how much cleverness RVO and move semantic bring to the table there is still complicated cases where a push_back is likely to make unnecessary copies (or move). For example, with the traditional insert() function of a std::map, you have to create a temporary, which will then be copied into a std::pair<Key, Value>, which will then be copied into the map :
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(4, Complicated(anInt, aDouble, aString)));
// should be easier for the optimizer
m.emplace(4, anInt, aDouble, aString);
So why didn't they implement the right version of emplace_back in MSVC? Actually, it bugged me too a while ago, so I asked the same question on the Visual C++ blog. Here is the answer from Stephan T Lavavej, the official maintainer of the Visual C++ standard library implementation at Microsoft.
Q: Are beta 2 emplace functions just some kind of placeholder right now?
A: As you may know, variadic templates
aren't implemented in VC10. We
simulate them with preprocessor
machinery for things like
make_shared<T>(), tuple, and the new
things in <functional>. This
preprocessor machinery is relatively
difficult to use and maintain. Also,
it significantly affects compilation
speed, as we have to repeatedly
include subheaders. Due to a
combination of our time constraints
and compilation speed concerns, we
haven't simulated variadic templates
in our emplace functions.
When variadic templates are
implemented in the compiler, you can
expect that we'll take advantage of
them in the libraries, including in
our emplace functions. We take
conformance very seriously, but
unfortunately, we can't do everything
all at once.
It's an understandable decision. Everyone who tried just once to emulate variadic template with preprocessor horrible tricks knows how disgusting this stuff gets.
emplace_back shouldn't take an argument of type vector::value_type, but instead variadic arguments that are forwarded to the constructor of the appended item.
template <class... Args> void emplace_back(Args&&... args);
It is possible to pass a value_type which will be forwarded to the copy constructor.
Because it forwards the arguments, this means that if you don't have rvalue, this still means that the container will store a "copied" copy, not a moved copy.
std::vector<std::string> vec;
vec.emplace_back(std::string("Hello")); // moves
std::string s;
vec.emplace_back(s); //copies
But the above should be identical to what push_back does. It is probably rather meant for use cases like:
std::vector<std::pair<std::string, std::string> > vec;
vec.emplace_back(std::string("Hello"), std::string("world"));
// should end up invoking this constructor:
//template<class U, class V> pair(U&& x, V&& y);
//without making any copies of the strings
Optimization for emplace_back can be demonstrated in next example.
For emplace_back constructor A (int x_arg) will be called. And for
push_back A (int x_arg) is called first and move A (A &&rhs) is called afterwards.
Of course, the constructor has to be marked as explicit, but for current example is good to remove explicitness.
#include <iostream>
#include <vector>
class A
{
public:
A (int x_arg) : x (x_arg) { std::cout << "A (x_arg)\n"; }
A () { x = 0; std::cout << "A ()\n"; }
A (const A &rhs) noexcept { x = rhs.x; std::cout << "A (A &)\n"; }
A (A &&rhs) noexcept { x = rhs.x; std::cout << "A (A &&)\n"; }
private:
int x;
};
int main ()
{
{
std::vector<A> a;
std::cout << "call emplace_back:\n";
a.emplace_back (0);
}
{
std::vector<A> a;
std::cout << "call push_back:\n";
a.push_back (1);
}
return 0;
}
output:
call emplace_back:
A (x_arg)
call push_back:
A (x_arg)
A (A &&)
One more example for lists:
// constructs the elements in place.
emplace_back("element");
// creates a new object and then copies (or moves) that object.
push_back(ExplicitDataType{"element"});
Specific use case for emplace_back: If you need to create a temporary object which will then be pushed into a container, use emplace_back instead of push_back. It will create the object in-place within the container.
Notes:
push_back in the above case will create a temporary object and move it
into the container. However, in-place construction used for emplace_back would be more
performant than constructing and then moving the object (which generally involves some copying).
In general, you can use emplace_back instead of push_back in all the cases without much issue. (See exceptions)
A nice code for the push_back and emplace_back is shown here.
http://en.cppreference.com/w/cpp/container/vector/emplace_back
You can see the move operation on push_back and not on emplace_back.
emplace_back conforming implementation will forward arguments to the vector<Object>::value_typeconstructor when added to the vector. I recall Visual Studio didn't support variadic templates, but with variadic templates will be supported in Visual Studio 2013 RC, so I guess a conforming signature will be added.
With emplace_back, if you forward the arguments directly to vector<Object>::value_type constructor, you don't need a type to be movable or copyable for emplace_back function, strictly speaking. In the vector<NonCopyableNonMovableObject> case, this is not useful, since vector<Object>::value_type needs a copyable or movable type to grow.
But note that this could be useful for std::map<Key, NonCopyableNonMovableObject>, since once you allocate an entry in the map, it doesn't need to be moved or copied ever anymore, unlike with vector, meaning that you can use std::map effectively with a mapped type that is neither copyable nor movable.

push_back vs emplace_back

I'm a bit confused regarding the difference between push_back and emplace_back.
void emplace_back(Type&& _Val);
void push_back(const Type& _Val);
void push_back(Type&& _Val);
As there is a push_back overload taking a rvalue reference I don't quite see what the purpose of emplace_back becomes?
In addition to what visitor said :
The function void emplace_back(Type&& _Val) provided by MSCV10 is non conforming and redundant, because as you noted it is strictly equivalent to push_back(Type&& _Val).
But the real C++0x form of emplace_back is really useful: void emplace_back(Args&&...);
Instead of taking a value_type it takes a variadic list of arguments, so that means that you can now perfectly forward the arguments and construct directly an object into a container without a temporary at all.
That's useful because no matter how much cleverness RVO and move semantic bring to the table there is still complicated cases where a push_back is likely to make unnecessary copies (or move). For example, with the traditional insert() function of a std::map, you have to create a temporary, which will then be copied into a std::pair<Key, Value>, which will then be copied into the map :
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(4, Complicated(anInt, aDouble, aString)));
// should be easier for the optimizer
m.emplace(4, anInt, aDouble, aString);
So why didn't they implement the right version of emplace_back in MSVC? Actually, it bugged me too a while ago, so I asked the same question on the Visual C++ blog. Here is the answer from Stephan T Lavavej, the official maintainer of the Visual C++ standard library implementation at Microsoft.
Q: Are beta 2 emplace functions just some kind of placeholder right now?
A: As you may know, variadic templates
aren't implemented in VC10. We
simulate them with preprocessor
machinery for things like
make_shared<T>(), tuple, and the new
things in <functional>. This
preprocessor machinery is relatively
difficult to use and maintain. Also,
it significantly affects compilation
speed, as we have to repeatedly
include subheaders. Due to a
combination of our time constraints
and compilation speed concerns, we
haven't simulated variadic templates
in our emplace functions.
When variadic templates are
implemented in the compiler, you can
expect that we'll take advantage of
them in the libraries, including in
our emplace functions. We take
conformance very seriously, but
unfortunately, we can't do everything
all at once.
It's an understandable decision. Everyone who tried just once to emulate variadic template with preprocessor horrible tricks knows how disgusting this stuff gets.
emplace_back shouldn't take an argument of type vector::value_type, but instead variadic arguments that are forwarded to the constructor of the appended item.
template <class... Args> void emplace_back(Args&&... args);
It is possible to pass a value_type which will be forwarded to the copy constructor.
Because it forwards the arguments, this means that if you don't have rvalue, this still means that the container will store a "copied" copy, not a moved copy.
std::vector<std::string> vec;
vec.emplace_back(std::string("Hello")); // moves
std::string s;
vec.emplace_back(s); //copies
But the above should be identical to what push_back does. It is probably rather meant for use cases like:
std::vector<std::pair<std::string, std::string> > vec;
vec.emplace_back(std::string("Hello"), std::string("world"));
// should end up invoking this constructor:
//template<class U, class V> pair(U&& x, V&& y);
//without making any copies of the strings
Optimization for emplace_back can be demonstrated in next example.
For emplace_back constructor A (int x_arg) will be called. And for
push_back A (int x_arg) is called first and move A (A &&rhs) is called afterwards.
Of course, the constructor has to be marked as explicit, but for current example is good to remove explicitness.
#include <iostream>
#include <vector>
class A
{
public:
A (int x_arg) : x (x_arg) { std::cout << "A (x_arg)\n"; }
A () { x = 0; std::cout << "A ()\n"; }
A (const A &rhs) noexcept { x = rhs.x; std::cout << "A (A &)\n"; }
A (A &&rhs) noexcept { x = rhs.x; std::cout << "A (A &&)\n"; }
private:
int x;
};
int main ()
{
{
std::vector<A> a;
std::cout << "call emplace_back:\n";
a.emplace_back (0);
}
{
std::vector<A> a;
std::cout << "call push_back:\n";
a.push_back (1);
}
return 0;
}
output:
call emplace_back:
A (x_arg)
call push_back:
A (x_arg)
A (A &&)
One more example for lists:
// constructs the elements in place.
emplace_back("element");
// creates a new object and then copies (or moves) that object.
push_back(ExplicitDataType{"element"});
Specific use case for emplace_back: If you need to create a temporary object which will then be pushed into a container, use emplace_back instead of push_back. It will create the object in-place within the container.
Notes:
push_back in the above case will create a temporary object and move it
into the container. However, in-place construction used for emplace_back would be more
performant than constructing and then moving the object (which generally involves some copying).
In general, you can use emplace_back instead of push_back in all the cases without much issue. (See exceptions)
A nice code for the push_back and emplace_back is shown here.
http://en.cppreference.com/w/cpp/container/vector/emplace_back
You can see the move operation on push_back and not on emplace_back.
emplace_back conforming implementation will forward arguments to the vector<Object>::value_typeconstructor when added to the vector. I recall Visual Studio didn't support variadic templates, but with variadic templates will be supported in Visual Studio 2013 RC, so I guess a conforming signature will be added.
With emplace_back, if you forward the arguments directly to vector<Object>::value_type constructor, you don't need a type to be movable or copyable for emplace_back function, strictly speaking. In the vector<NonCopyableNonMovableObject> case, this is not useful, since vector<Object>::value_type needs a copyable or movable type to grow.
But note that this could be useful for std::map<Key, NonCopyableNonMovableObject>, since once you allocate an entry in the map, it doesn't need to be moved or copied ever anymore, unlike with vector, meaning that you can use std::map effectively with a mapped type that is neither copyable nor movable.