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?
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.
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.
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