Should I use C++11 emplace_back with pointers containers?

Zhen picture Zhen · Apr 3, 2013 · Viewed 22.7k times · Source

Having a usual Base -> Derived hierarchy, like:

class Fruit { ... };
class Pear : Fruit { ... };
class Tomato : Fruit { ... };

std::vector<Fruit*> m_fruits;

Does it make sense (e.g: is performance better) to use emplace_back instead of push_back?

std::vector::emplace_back( new Pear() );
std::vector::emplace_back( new Tomato() );

Answer

Snps picture Snps · Apr 3, 2013

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>());