#include <memory>

template<typename D, typename B>
std::unique_ptr<D> static_cast_ptr(std::unique_ptr<B>& base)
{
    return std::unique_ptr<D>(static_cast<D*>(base.release()));
}
 
template<typename D, typename B>
std::unique_ptr<D> static_cast_ptr(std::unique_ptr<B>&& base)
{
    return std::unique_ptr<D>(static_cast<D*>(base.release()));
}

class Base
{
public:
    virtual ~Base() {}
};

class Derived : public Base
{
public:
    virtual ~Derived() {}
};

int main()
{
    std::unique_ptr<Base> base_ptr(new Derived);
    auto derived_ptr = static_cast_ptr<Derived>(base_ptr);
}