unique_ptr smart shared_ptr make_unique c++ stl c++11 smart-pointers unique-ptr

c++ - smart - shared_ptr



¿Por qué no puedo push_back un unique_ptr en un vector? (2)

¿Qué está mal con este programa?

#include <memory> #include <vector> int main() { std::vector<std::unique_ptr<int>> vec; int x(1); std::unique_ptr<int> ptr2x(&x); vec.push_back(ptr2x); //This tiny command has a vicious error. return 0; }

El error:

$ g++ -std=gnu++0x main.cpp In file included from c:/mingw/bin/../lib/gcc/mingw32/4.5.0/include/c+ +/mingw32/bits/c++allocator.h:34:0, from c:/mingw/bin/../lib/gcc/mingw32/4.5.0/include/c+ +/bits/allocator.h:48, from c:/mingw/bin/../lib/gcc/mingw32/4.5.0/include/c+ +/memory:64, from main.cpp:6: c:/mingw/bin/../lib/gcc/mingw32/4.5.0/include/c++/bits/unique_ptr.h: I n member function ''void __gnu_cxx::new_allocator<_Tp>::construct(_Tp*, const _Tp&) [with _Tp = std::unique_ptr<int>, _Tp* = std::unique_ptr< int>*]'': c:/mingw/bin/../lib/gcc/mingw32/4.5.0/include/c++/bits/stl_vector.h:74 5:6: instantiated from ''void std::vector<_Tp, _Alloc>::push_back(con st value_type&) [with _Tp = std::unique_ptr<int>, _Alloc = std::alloca tor<std::unique_ptr<int> >, value_type = std::unique_ptr<int>]'' main.cpp:16:21: instantiated from here c:/mingw/bin/../lib/gcc/mingw32/4.5.0/include/c++/bits/unique_ptr.h:20 7:7: error: deleted function ''std::unique_ptr<_Tp, _Tp_Deleter>::uniqu e_ptr(const std::unique_ptr<_Tp, _Tp_Deleter>&) [with _Tp = int, _Tp_D eleter = std::default_delete<int>, std::unique_ptr<_Tp, _Tp_Deleter> = std::unique_ptr<int>]'' c:/mingw/bin/../lib/gcc/mingw32/4.5.0/include/c++/ext/new_allocator.h: 105:9: error: used here In file included from c:/mingw/bin/../lib/gcc/mingw32/4.5.0/include/c+ +/vector:69:0, from main.cpp:7: c:/mingw/bin/../lib/gcc/mingw32/4.5.0/include/c++/bits/unique_ptr.h: I n member function ''void std::vector<_Tp, _Alloc>::_M_insert_aux(std::v ector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {const std::u nique_ptr<int>&}, _Tp = std::unique_ptr<int>, _Alloc = std::allocator< std::unique_ptr<int> >, std::vector<_Tp, _Alloc>::iterator = __gnu_cxx ::__normal_iterator<std::unique_ptr<int>*, std::vector<std::unique_ptr <int> > >, typename std::vector<_Tp, _Alloc>::_Base::_Tp_alloc_type::p ointer = std::unique_ptr<int>*]'': c:/mingw/bin/../lib/gcc/mingw32/4.5.0/include/c++/bits/stl_vector.h:74 9:4: instantiated from ''void std::vector<_Tp, _Alloc>::push_back(con st value_type&) [with _Tp = std::unique_ptr<int>, _Alloc = std::alloca tor<std::unique_ptr<int> >, value_type = std::unique_ptr<int>]'' main.cpp:16:21: instantiated from here c:/mingw/bin/../lib/gcc/mingw32/4.5.0/include/c++/bits/unique_ptr.h:20 7:7: error: deleted function ''std::unique_ptr<_Tp, _Tp_Deleter>::uniqu e_ptr(const std::unique_ptr<_Tp, _Tp_Deleter>&) [with _Tp = int, _Tp_D eleter = std::default_delete<int>, std::unique_ptr<_Tp, _Tp_Deleter> = std::unique_ptr<int>]'' c:/mingw/bin/../lib/gcc/mingw32/4.5.0/include/c++/bits/vector.tcc:314: 4: error: used here


Necesitas mover el unique_ptr :

vec.push_back(std::move(ptr2x));

unique_ptr garantiza que un único contenedor unique_ptr tenga la propiedad del puntero retenido. Esto significa que no puede hacer copias de un unique_ptr (porque entonces dos unique_ptr s tendrían propiedad), por lo que solo puede moverlo.

Sin embargo, tenga en cuenta que su uso actual de unique_ptr es incorrecto. No puede usarlo para administrar un puntero a una variable local. La vida útil de una variable local se gestiona automáticamente: las variables locales se destruyen cuando termina el bloque (por ejemplo, cuando la función retorna, en este caso). Necesitas asignar dinámicamente el objeto:

std::unique_ptr<int> ptr(new int(1));


unique_ptr no tiene constructor de copia. Crea una instancia y luego le pide al std::vector que copie esa instancia durante la inicialización.

error: deleted function ''std::unique_ptr<_Tp, _Tp_Deleter>::uniqu e_ptr(const std::unique_ptr<_Tp, _Tp_Deleter>&) [with _Tp = int, _Tp_D eleter = std::default_delete<int>, std::unique_ptr<_Tp, _Tp_Deleter> = std::unique_ptr<int>]''

La clase satisface los requisitos de MoveConstructible y MoveAssignable, pero no los requisitos de CopyConstructible o CopyAssignable.

Lo siguiente funciona con las nuevas llamadas emplace .

std::vector< std::unique_ptr< int > > vec; vec.emplace_back( new int( 1984 ) );

Consulte el uso de unique_ptr con contenedores de biblioteca estándar para leer más.