emplace_back c++ constructor stdvector emplace

c++ - ¿Por qué no funciona este uso de emplace_back con el constructor de copia eliminado?



insert std vector (3)

Cuando el almacenamiento interno del vector crezca, deberá mover los elementos del almacenamiento anterior al nuevo. Al eliminar el constructor de copia, también evita que se genere el constructor de movimiento predeterminado.

Tengo un tipo del que he eliminado el constructor de copia, y me gustaría tener un vector de este tipo, por lo que necesito crear todos los elementos a través de emplace_back . Pero, emplace_back parece requerir un constructor de copia, ya que el compilador advierte que no se puede crear emplace_back instancia de emplace_back porque el constructor de copia se ha eliminado. ¿Por qué necesita un constructor de copia? Pensé que el punto emplace_back de emplace_back era construir el vector sin copiar nada. ¿Puedo incluso tener un vector de objetos que no tienen un constructor de copia?

class MyType { public: MyType(std::array<double, 6> a) {} MyType(const MyType& that) = delete; }; int main() { std::vector<MyType> v; std::array<double, 6> a = {1,2,3,4,5,6}; v.emplace_back(a); }

El compilador es clang / llvm.


Para poder llamar a emplace_back, su tipo debe ser EmplaceConstructible o MoveInsertible . Debe dar un constructor de movimiento a su clase si ha eliminado el constructor de copia. (Marque this para los requisitos de emplace_back)

MyType(MyType &&a) {/*code*/} //move constructor


Si intentas ejecutar este código:

// Example program #include <iostream> #include <string> #include <array> #include <vector> class MyType { public: MyType(std::array<double, 6> a) { std::cout<< "constructed from array/n"; } MyType(const MyType& that){ std::cout<< "copy/n"; } MyType(MyType&& that){ std::cout<< "move/n"; } }; int main() { std::vector<MyType> v; std::array<double, 6> a = {1,2,3,4,5,6}; v.emplace_back(a); }

Obtendrá el siguiente resultado:

construido a partir de matriz

Demo en vivo

Está claro que solo se llama al constructor de std::Array . Por lo tanto, no hay necesidad de copy constructor . Pero al mismo tiempo, si deleted el copy constructor , el compilador generará un error (al menos en dos compiladores que probé cpp.sh/9v5w second ). Creo que algunos compiladores comprobarán la existencia de un copy constructor de copy constructor cuando usen emplace_back, incluso si no es necesario en este caso práctico, mientras que otros no lo harán. No sé qué es estándar aquí (qué compilador es correcto o incorrecto).