Подтвердить что ты не робот

Векторный emplace_back

Не могли бы вы объяснить, как работает "совершенная переадресация"?

Я читал, что вектор emplace_back не нужно копировать и перемещать объекты, потому что его аргумент реализован как вариационный шаблон.

std::vector<T>::emplace_back(_Args&&... __args)

Можете ли вы описать это более подробно? Почему он не копируется и не перемещается?

4b9b3361

Ответ 1

emplace_back непосредственно конструирует элемент в правильном положении в векторе. Подумайте об этом, как будто

vector<T> v;
v.emplace_back(a,b,c);

преобразуется в (idx - новый индекс)

new (v.data()+idx) T(a,b,c);

(Реальность немного сложнее, включая перенаправление аргументов как std::forward<_Args>()..., но это может быть более запутанным для получения ключа операций emplace)

Ответ 2

В emplace_back на самом деле две вещи:

  • Вы не передаете объект типа T, а аргументы конструктору T. Таким образом, конструкция объекта задерживается: вектор расширяется для размещения в памяти, необходимой для нового объекта, и конструктор вызывается для инициализировал объект в векторе. Шаблон Variadic не имеет ничего общего с копиями, они позволяют перенаправлять переменное число аргументов конструктору.
  • Аргументы для самих конструкторов не копируются, потому что они передаются как ссылки rvalues, а std:: move используется для пересылки их в конструктор. В принципе, перемещение семантики позволяет избежать глубоких копий объектов.