dynamic_pointer_cast for std::unique_ptr
Since it's a template function, it doesn't need to be marked inline.

It would be nice to handle custom deleters too. We can access the deleter with ptr_.get_deleter().