Should I use C++11 emplace_back with pointers containers?
Don't use raw pointers, use std::unique_ptr
like this:
std::vector<std::unique_ptr<Fruit>> m_fruits;
And as you can't copy construct a std::unique_ptr
you must use emplace_back
(although you can use push_back
with std::move
).
m_fruits.emplace_back(new Pear()); m_fruits.emplace_back(new Tomato());
Edit:
As it appears that using std::vector<std::unique_ptr<T>>::emplace_back
and new
can leak if the std::vector
needs and fails to reallocate memory, my recommended approach (until C++14 introduces std::make_unique
) is to use push_back
like this:
m_fruits.push_back(std::unique_ptr<Fruit>(new Pear()));
m_fruits.push_back(std::unique_ptr<Fruit>(new Tomato()));
Or using std::make_unique
:
m_fruits.push_back(std::make_unique<Pear>());
m_fruits.push_back(std::make_unique<Tomato>());
Pointers are scalar types and therefore literal types, and so copy, move and emplace construction (from an lvalue or rvalue) are all equivalent and will usually compile to identical code (a scalar copy). push_back
is clearer that you're performing a scalar copy, whereas emplace_back
should be reserved for emplace construction calling a non-copy- or move- constructor (e.g. a converting or multi-argument constructor).
If your vector should hold std::unique_ptr<Fruit>
instead of raw pointers (to prevent memory leaks) then because you're calling a converting constructor emplace_back
would be more correct. However that can still leak if extending the vector fails, so in that case you should use push_back(make_unique<Pear>())
etc.