I want to have a vector of pointers to objects in my class. To avoid making a destructor for it I wanted to use std::unique_ptr, as the objects are created/owned/destructed in my class, but I have a compiler error I can’t understand. Next code will serve as a short sample for my problem:
std::unique_ptr<int> createPtr(int value)
{
std::unique_ptr<int> ptr(new int(value));
return ptr;
};
int main()
{
std::vector<std::unique_ptr<int>> vec;
vec.push_back(createPtr(1));
std::unique_ptr<int> ptr = createPtr(2);
vec.push_back(ptr);//error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>'
}
Can you please explain me why I get this error and what is the correct usage for std::unique_ptr?
Consider the
vec.push_back(). It has two overloads which take eitherconst std::unique_ptr<int>&orstd::unique_ptr<int>&&. The first overload can never be used. This is because thevector<>requires the type to be assignable, or movable (C++11 addition). ‘Assignability’ implies copying.push_back(const T&)will try to copy (assign) the incoming value to the new space at the end of the container.std::unique_ptr<>represents a resource that is owned by a single owner. By copying it (the pointer) multiple owners would be present. Because of thatunique_ptris not copyable.Having said all of it, you can only use the
T&&overload.createPtr()returnsstd::unique_ptr<int>, but as this is a temporary result (function return value) it is considered a rvalue reference (implicitly). That is why this can be used.ptris just astd::unique_ptr<int>which is a lvalue reference (no matter if you put && next to it, as named rvalues are still treated as lvalues). Lvalue is never implicitly converted to rvalue (completely unsafe). But you can basically tell the compiler “Ok, you can take the object I pass you, and I promise I won’t expect the argument to be left intact” by usingstd::move().