Context
I am trying to forward ownership of a std::unique_ptr
through a lambda. But because std::function
s must always be copyable, capturing a std::unique_ptr
is not possible. I am trying to use a workaround described here: https://stackoverflow.com/a/29410239/6938024
Example
Here is my example which uses the described workaround
struct DataStruct
{
/*...*/
};
class ISomeInterface
{
/*...*/
};
class SomeOtherClass
{
public:
void GetSomethingAsync(std::function<void(DataStruct)> resultHandler);
};
class MyClass
{
void Foo(
std::unique_ptr<ISomeInterface> ptr,
std::function<void(std::unique_ptr<ISomeInterface>, DataStruct)> callback)
{
// I just want to "pass through" ownership of ptr
std::shared_ptr sharedPtr =
std::make_shared<std::unique_ptr<ISomeInterface>>(std::move(ptr));
mSomeOtherClass.GetSomethingAsync(
[cb = std::move(callback), sharedPtr](DataStruct data)
{
auto unique = std::move(*sharedPtr.get());
cb(std::move(unique), data);
});
}
SomeOtherClass mSomeOtherClass;
};
Question
Does moving away the std::unique_ptr
, which is managed by the std::shared_ptr
cause any risk? My assumption would be, that the std::shared_ptr
should try to delete the std::unique_ptr
object, which is now dangling.
Is this code "safe"? Could the std::shared_ptr
try to delete a dangling pointer, or can it know, that its managed object was moved away?
I would appreciate to understand the behaviour in this case more clearly. Someone please explain the specifics of what happens with the smart pointers here.
EDIT: Changed a wrong line in the example.
cb(std::move(*sharedPtr), data);
was changed to cb(std::move(unique), data);