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
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).