[c++] push_back vs emplace_back
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
I'm a bit confused regarding the difference between
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 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.
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.
A nice code for the push_back and emplace_back is shown here.
You can see the move operation on push_back and not on emplace_back.