I try to move some unique_ptr in a vector during it declaration and I get a error. I think that I make a copy without knowing it.
I don't understand why I get the problem at the declaration while it works very well during a push_back.
I simplified the problem in few lines.
#include <iostream>
#include <vector>
#include <memory>
using namespace std;
int main() {
unique_ptr<int> i1 = make_unique<int>(142);
unique_ptr<int> i2 = make_unique<int>(242);
unique_ptr<int> i3 = make_unique<int>(342);
vector<unique_ptr<int>> v;
//Those lines work
v.push_back(move(i1));
v.push_back(move(i2));
v.push_back(move(i3));
//ERROR
vector<unique_ptr<int>> v2 {move(i1), move(i2), move(i3)};
return 0;
}
The error is :
use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const
std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp =
std::default_delete<int>]'
{ ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
What am I missing ?
Thanks !
A unique_ptr can only be moved. This means that the ownership of the memory resource is transferred to another unique_ptr and the original unique_ptr no longer owns it. We recommend that you restrict an object to one owner, because multiple ownership adds complexity to the program logic.
Yes, you can compare it to nullptr after the move and it is guaranteed to compare equal. This is clearly true after calling release(). But std::move doesn't call release(). So how does the compiler know to restore the invariant of the unique_ptr?
An unique_ptr has exclusive ownership of the object it points to and will destroy the object when the pointer goes out of scope. A unique_ptr explicitly prevents copying of its contained pointer. Instead, the std::move function has to be used to transfer ownership of the contained pointer to another unique_ptr .
Use unique_ptr when you want to have single ownership(Exclusive) of the resource. Only one unique_ptr can point to one resource. Since there can be one unique_ptr for single resource its not possible to copy one unique_ptr to another. A shared_ptr is a container for raw pointers.
When you do
vector<unique_ptr<int>> v2 {move(i1), move(i2), move(i3)};
you are not actually moving directly into the vector v2
. Instead the compiler will create a std::initializer_list
of the moved unique pointers, and pass that list object to the std::vector
constructor which will then attempt to copy the elements from the initializer list.
Unfortunately I know of no way to solve the problem, of using the intermediate initializer list to initialize a vector of unique pointers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With