Alternatives of static_pointer_cast for unique_ptr

#Raw pointers

The solution for your problem is to get the raw (non-owning) pointer and cast it – then just let the raw pointer go out of scope and let the remaining unique_ptr<Base> control the lifetime of the owned object.

Like this:

unique_ptr<Base> foo = fooFactory();

{
    Base* tempBase = foo.get();
    Derived* tempDerived = static_cast<Derived*>(tempBase);
} // tempBase and tempDerived go out of scope here, but foo remains -> no need to delete

#Unique_pointer_cast
The other option is to use the release() function of unique_ptr to wrap it into another unique_ptr.

Like this:

template<typename TO, typename FROM>
unique_ptr<TO> static_unique_pointer_cast (unique_ptr<FROM>&& old){
    return unique_ptr<TO>{static_cast<TO*>(old.release())};
    // conversion: unique_ptr<FROM>->FROM*->TO*->unique_ptr<TO>
}

unique_ptr<Base> foo = fooFactory();

unique_ptr<Derived> foo2 = static_unique_pointer_cast<Derived>(std::move(foo));

Remember that this invalidates the old pointer foo

#Reference from raw pointers
Just for completeness of the answer, this solution was actually proposed as a small modification of the raw pointers by the OP in the comments.

Similar to using raw pointers one can cast the raw pointers and then create a reference out of them by derefering. In this case it is important to guarantee that the lifetime of the created reference does not exceed the lifetime of the unique_ptr.

Sample:

unique_ptr<Base> foo = fooFactory();
Derived& bar = *(static_cast<Derived*>(foo.get()));
// do not use bar after foo goes out of scope

Leave a Comment