push_back emplace_back c++ constructor stdvector

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 .