Это всегда вопрос.
Прежде всего, это действительно зависит от того, поддерживает ли ваш компилятор семантику перемещения C ++ 11 или нет, поскольку это кардинально меняет аспекты проблемы.
Для тех, кто застрял в C ++ 03
Есть несколько вариантов:
std::list<MyClass> list;
list.push_front(MyClass());
Даже если семантически имеется копия, оптимизатор может удалить большую частьизбыточные / мертвые магазины.Большинство оптимизаторов требуют, чтобы было доступно определение конструктора по умолчанию и конструктора копирования.
boost::ptr_deque<MyClass> deque;
std::auto_ptr<MyClass> p(new MyClass());
deque.push_front(p);
ptr_vector
можно использовать, если вы замените push_front
на push_back
, иначе это будет немного расточительно.Это позволяет избежать большинства накладных расходов памяти std::list<MyClass*>
и имеет дополнительный бонус автоматической обработки памяти.
boost::stable_vector<MyClass> svec;
svec.push_back(MyClass());
// ~~~~
Существует одна копия (как со списком), но гарантия того, что дальнейшая копия не должна быть сделанавнутри контейнера (как со списком).Он также позволяет выполнять несколько больше операций, чем list (например, произвольный доступ), за счет того, что он медленнее для вставки в середине для больших контейнеров.
Для тех, кто пользуется C ++ 11
std::list<MyClass> list;
list.push_front(MyClass());
не создает никакой копии, вместо этого происходит операция перемещения.
Также возможно использовать новые операции, предоставленные для создания объектов на месте:
std::list<MyClass> list;
list.emplace_front();
создаст новый MyClass
непосредственно внутри узла, без копирования, без перемещения.
И, наконец, вы можете пожелать более компактное представление или другие операции над контейнером, в этом случае:
std::vector<std::unique_ptr<MyClass>> vec;
vec.emplace_back(new MyClass());
Предлагает вам произвольный доступ и меньшую нагрузку на память.