emplace back () no se comporta como se espera


Escribí un programa simple para jugar con la creación in situ de objetos dentro de contenedores de bibliotecas estándar. Esto es lo que escribí:

#include <vector>
#include <iostream>

class AB
{
public:
   explicit AB(int n);
   AB(const AB& other) = delete;
   AB(AB&& other);
   AB& operator=(const AB& other) = delete;
   AB& operator=(AB&& other) = default;
private:
   int i;
};

AB::AB(int n): i( n )
{
   std::cout << "Object created." << std::endl;
};

AB::AB(AB&& other): i( std::move(other.i) )
{
   std::cout << "Object moved." << std::endl;
};

int main()
{
   std::vector< AB > v;
   v.emplace_back(1);
   v.emplace_back(2);
   v.emplace_back(3);
};

Lo compilé con g++ (versión 4.8.2). Después de ejecutar la salida, obtuve:

Object created.
Object created.
Object moved.
Object created.
Object moved.
Object moved.

Pero yo esperaba algo como esto:

Object created.
Object created.
Object created.

Pensé que el objetivo de emplacement era deshacerse de las llamadas constructoras del movimiento. ¿Hay algún requisito en la clase AB que no se cumpla?

Gracias por su ayuda.

Author: Griwes, 2014-05-30

2 answers

El problema es que su vector se está redimensionando a medida que agrega más elementos, lo que resulta en movimientos adicionales. Si reserva suficiente capacidad al principio, obtendrá el resultado esperado:

   std::vector< AB > v;
   v.reserve(3);
   v.emplace_back(1);
   v.emplace_back(2);
   v.emplace_back(3);

Da

Object created.
Object created.
Object created.

Sobre el ccg 4.8.2. Tenga en cuenta que puede rastrear el crecimiento del vector en su código original mirando v.capacity().

 31
Author: juanchopanza,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-30 06:40:53

El punto de emplazamiento es deshacerse de las llamadas del constructor de COPIA. Probablemente está moviendo objetos debido al cambio de tamaño del vector cuando está lleno. Mover un objeto está bien. Copiar un objeto es caro.

 2
Author: Ben,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-30 06:34:11