Suppose class D
is derived from class B
. What is the best way to convert a std::shared_ptr<std::unique_ptr<D>>
to std::shared_ptr<std::unique_ptr<B>>
? The solution should not increment / decrement the std::shared_ptr
counter and should not make copy of the std::unique_ptr
.
The naive approach does not work:
#include <memory>
struct B {
virtual void msg() {
printf("BASE\n");
}
virtual ~B() = default;
};
struct D: B {
D() = default;
void msg() override {
printf("DERIVED\n");
}
};
int main() {
std::shared_ptr<std::unique_ptr<D>> derivedPtr = std::make_shared<std::unique_ptr<D>>(std::make_unique<D>());
std::shared_ptr<std::unique_ptr<B>> basePtr = static_cast<std::shared_ptr<std::unique_ptr<B>>>(std::move(derivedPtr));
basePtr->get()->msg();
}
The compiler says that this static_cast
is impossible.
This is impossible (in any form) because std::unique_ptr<B>
and std::unique_ptr<D>
are not in any form related by inheritance.
Conceptually this is wrong and this is also the first time I have seen a shared pointer holding a unique pointer. That itself seems like a big red flag on the whole approach and makes it sound like a XY problem.
Why does the shared pointer hold the unique pointer instead of holding the object that the unique pointer holds directly?