push_back emplace_back c++ stl c++11

c++ - emplace_back vs push_back



vector''s emplace_back (2)

¿Puedes explicar cómo funciona el "reenvío perfecto"?

Leí que emplace_back de ese vector no necesita copiar ni mover objetos, porque su argumento se implementa como plantilla variadic.

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

¿Puedes describirlo con más detalle? ¿Por qué no se copiará ni se moverá?


En realidad, hay dos cosas que suceden en emplace_back:

  1. No pasa un objeto de tipo T sino argumentos a un constructor de T. De esta forma, la construcción del objeto se retrasa: el vector se extiende para acomodar la memoria que necesita el nuevo objeto, y se llama al constructor para inicializar el objeto en el vector. Las plantillas variables no tienen nada que ver con las copias, solo permiten reenviar un número variable de argumentos al constructor.
  2. Los argumentos a los propios constructores no se copian porque se pasan como referencias rvalues ​​y std :: move se usa para reenviarlos al constructor. Básicamente, la semántica del movimiento evita copias profundas de los objetos.

emplace_back construye directamente el elemento en la posición correcta en el vector. Piense en ello como si

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

se transforma en (idx es el nuevo índice)

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

(La realidad es un poco más compleja que implica reenviar los argumentos como std::forward<_Args>()... pero eso podría ser más confuso para obtener la clave de operaciones de colocación)