Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the reasoning behind std::unique_ptr<T>'s constructor from T* being explicit?

As std::unique_ptr provides a handy way to avoid memory leaks and ensure exception safety, it is sensible to pass them around rather than raw pointers. Thus, one may want (member) functions with a signature like

std::unique_ptr<some_type> foo(some data);

Unfortunately, when implementing such a function, one cannot simply

std::unique_ptr<some_type> foo(some data)
{
  return { new some_type(data) };                  // error
}

but must instead

std::unique_ptr<some_type> foo(some data)
{
  return std::move( std::unique_ptr<some_type>( new some_type(data) ) );   // awkward
}

because the constructor unique_ptr::unique_ptr(pointer) is explicit. What is the reasoning behind this constructor being explicit?

One motivation to make constructors explicit is to guard against unintended implicit type conversion. However, as unique_ptr cannot be passed by value, this should not really be a problem, should it?

like image 441
Walter Avatar asked Aug 28 '15 11:08

Walter


People also ask

What is the use of std :: unique_ptr?

std::unique_ptr is a smart pointer that owns and manages another object through a pointer and disposes of that object when the unique_ptr goes out of scope. The object is disposed of, using the associated deleter when either of the following happens: the managing unique_ptr object is destroyed.

What is the class template unique_ptr used for?

The uses of unique_ptr include providing exception safety for dynamically allocated memory, passing ownership of dynamically allocated memory to a function, and returning dynamically allocated memory from a function.

Does unique_ptr have copy constructor?

unique_ptr is not copyable, it is only moveable. This will directly affect Test, which is, in your second, example also only moveable and not copyable.

How does C++ unique_ptr work?

unique_ptr<> is one of the Smart pointer implementation provided by c++11 to prevent memory leaks. A unique_ptr object wraps around a raw pointer and its responsible for its lifetime. When this object is destructed then in its destructor it deletes the associated raw pointer.


1 Answers

unique_ptr takes ownership of passed pointer. Taking ownership should be explicit - you don't want some pointer to 'magically' become owned (and deleted) by some class (that was one of issues with deprecated std::auto_ptr).

for example:

void fun(std::unique_ptr<X> a) { .... }
X x;
fun(&x); // BOOM, deleting object on stack, fortunately it does not compile
fun(std::unique_ptr<X>(&x)); // compiles, but it's explicit and error is clearly visible

please note, that std::move is not required in return statement (special language exception - local variables as return arguments can be treated as 'moved').

Also - in C++14 you can use std::make_unique to make it less awkward:

return std::make_unique<some_data>(some_data_argument1, arg2);

(it can be also easily added to C++11 - read here)

like image 116
Hcorg Avatar answered Oct 16 '22 02:10

Hcorg