Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Move a unique_ptr with custom deleter to a shared_ptr

I have a function which creates a unique_ptr with a custom deleter and returns it:

auto give_unique_ptr() {     auto deleter = [](int* pi) {         delete pi;     };     int* i = new int{1234};     return std::unique_ptr<int, decltype(deleter)>(i, deleter); } 

In the client code of that function, I'd like to move the unique_ptr into a shared_ptr, but I don't know how to do that given that I don't know the decltype of my custom deleter outside of the function.

I guess it should look something like this:

auto uniquePtr = give_unique_ptr(); auto sharedPtr = std::shared_ptr<..??..>(std::move(uniquePtr)); 

What do I have to write instead of ..??.. to get the correct type?

If this is possible, will the shared_ptr behave nicely and call my custom deleter created inside the give_unique_ptr() function when it's usage count reaches zero?

like image 696
j00hi Avatar asked Jun 24 '15 18:06

j00hi


2 Answers

If you know (or want to explicitly type) the type of the object, then you can do this:

std::shared_ptr<int> sharedPtr(std::move(uniquePtr)); 

The constructor of std::shared_ptr will take care of the deletor.


If you, however, want the type to be inferred, then:

auto sharedPtr = make_shared_from(std::move(uniquePtr)); 

where make_shared_from is:

template<typename T, typename D> std::shared_ptr<T> make_shared_from(std::unique_ptr<T,D> && p) {    //D is deduced but it is of no use here!    //We need only `T` here, the rest will be taken     //care by the constructor of shared_ptr    return std::shared_ptr<T>(std::move(p)); }; 

Hope that helps.

like image 85
Nawaz Avatar answered Sep 29 '22 03:09

Nawaz


auto uniquePtr = give_unique_ptr(); auto sharedPtr = std::shared_ptr<decltype(uniquePtr)::element_type>(std::move(uniquePtr)); 

And yes, the shared_ptr will store - and later use - the custom deleter.

like image 32
T.C. Avatar answered Sep 29 '22 03:09

T.C.