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.