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 semantics bring to the table, there are 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.
template <class _Valty> void emplace_back(_Valty&& _Val)
version that takes a universal reference which provides perfect forwarding toexplicit
single argument constructors. – Quibblingpush_back
is preferable toemplace_back
? The only case I can think of is if a class were somehow copyable (T&operator=(constT&)
) but not construct-able (T(constT&)
), but I can't think of why one would ever want that. – Satisfiedemplace_back()
andpush_back()
will invoke the copy-constructor - i.e. both perform construction, i.e. neither perform assignment - so your suggested class would not fare any better with either. – Agonizingemplace_back
will "implicitly" callexplicit
constructors, which could lead to undesired behavior. (For heavy classes, I often make the copy c'torexplicit
leaving the move-c'tor implicit.v.emplace_back(x)
bit me by doing basicallyv.emplace_back(X(x))
when I hoped it to error and force me to writev.push_back(std::move(x))
.) – Satisfied