Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't unique_ptr infer the type of the deleter?

Let's say I want to use a custom deleter with an unique_ptr:

void custom_deleter(int* obj)
{
    delete obj; 
}

Why do I have to write this:

std::unique_ptr<int, void(*)(int*)> x(new int, custom_deleter);

instead of this:

std::unique_ptr<int> x(new int, custom_deleter); //does not compile

?

Can't the type of the deleter be inferred?

like image 699
rubix_addict Avatar asked Apr 15 '15 20:04

rubix_addict


People also ask

What happens when unique_ptr goes out of scope?

An​ unique_ptr has exclusive ownership of the object it points to and ​will destroy the object when the pointer goes out of scope.

When should we use unique_ptr?

When to use 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.

Is unique_ptr an example of Raii idiom?

yes, it's an RAII class.

What happens when you move a unique_ptr?

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.


1 Answers

For unique_ptr, the deleter is part of the type:

template <
    class T,
    class Deleter = std::default_delete<T>
> class unique_ptr;

As such, when you're constructing an object, you need to specify its type. The line you're writing:

std::unique_ptr<int> x(new int, custom_deleter);

is equivalent to:

std::unique_ptr<int, std::default_delete<int> > x(new int, custom_deleter);

And you cannot construct a std::default_delete<int> from custom_deleter.

The only way to infer the deleter type is to use template deduction on that part too:

template <typename T, typename Deleter>
std::unique_ptr<T, Deleter> make_unique_ptr(T* ptr, Deleter deleter) {
    return std::unique_ptr<T, Deleter>(ptr, deleter);
}
like image 79
Barry Avatar answered Oct 03 '22 17:10

Barry