c++ - push_back - ¿Por qué falla este std:: vector:: emplace_back?
c++ emplace back (1)
Me encuentro con un error de compilación que dice:
intentando hacer referencia a una función eliminada
#include <iostream>
#include <vector>
template <typename T>
struct Container
{
Container() = default;
Container(const Container& other) = delete;
Container(T* ptr) : ptr(ptr) {}
T* ptr;
~Container() { delete ptr; }
};
struct Foo { Foo(int a, int b) {} };
int main()
{
std::vector<Container<Foo>> myvector;
myvector.push_back(new Foo(1, 2)); // I understand why this doesn''t work.
myvector.emplace_back((new Foo(1, 2))); // I don''t understand why this fails
}
Entiendo por qué dice que intento hacer referencia a un constructor eliminado cuando hago std::vector::push_back()
, porque esto hace una copia y necesita llamar al constructor de copia , que eliminé.
Pero se supone que std::vector::emplace_back()
toma los argumentos de constructor del tipo que contiene. Cuando lo vuelvo a colocar, le doy un puntero a un Foo
, y esto debe ser enviado al constructor Container::Container(T* ptr)
.
¿Qué me estoy perdiendo?
Declarar un constructor de copia definido por el usuario no definirá un constructor de movimiento implícito; T
debe tener un constructor de copia o un constructor de movimiento para push_back
o emplace_back*
un objeto en un std::vector<T>
.
En los docs , consulte los requisitos en T
para crear una instancia de un std::vector<T>
. (No hay restricción aquí, sigue leyendo) .. énfasis mío
Los requisitos que se imponen a los elementos dependen de las operaciones reales realizadas en el contenedor . En general, se requiere que el tipo de elemento cumpla con los requisitos de Erasable, pero muchas funciones de los miembros imponen requisitos más estrictos . Este contenedor (pero no sus miembros) se puede crear una instancia con un tipo de elemento incompleto si el asignador satisface los requisitos de integridad del asignador.
Desde std::vector<...>::push_back
:
Requisitos de tipo
T
debe cumplir los requisitos de CopyInsertable para poder utilizar la sobrecarga (1).T
debe cumplir los requisitos de MoveInsertable para poder utilizar la sobrecarga (2).
Desde std::vector<...>::emplace_back
:
Requisitos de tipo
T
(el tipo de elemento del contenedor) debe cumplir los requisitos de MoveInsertable y EmplaceConstructible .
Para emplace_back
aquí, su código cumpliría los criterios de EmplaceConstructible , sin embargo, debido a que pueden ocurrir realizaciones, debe cumplir igualmente MoveInsertable .