1

I have a class Base and a derived class Derived. A function reads objects from a file descriptor and returns Base objects:

std::unique_ptr<Base> readNextThing();

And in some place I need to downcast the return value of this function to Derived. This is relevant since the input unique_ptr is a rvalue-reference, so we don't copy the pointer, but move it. In this specific context I don't mind the object being destroyed if it's not of Derived subtype, I just need to detect that the downcast pointer is null in that case.

I could do:

template<typename T, typename U>
std::unique_ptr<T> dynamic_unique_cast(std::unique_ptr<U> && unique)
{
    T * t = dynamic_cast<T*>(unique.get());
    if(t) { unique.release(); }  //Transfer ownership
    return std::unique_ptr<T>(t);
}

and

std::unique_ptr<Derived> d = dynamic_unique_cast<Derived>(readNextThing());
  1. Is there a built-in function for doing this?
  2. Is there any risk of memory leak in the above code if an exception occurs?
Amir Kirsh
  • 12,564
  • 41
  • 74
galinette
  • 8,896
  • 2
  • 36
  • 87

1 Answers1

2

Unfortunately std::dynamic_pointer_cast doesn't work on unique_ptr - there's no reason it couldn't work on an rvalue unique_ptr, except that perhaps the behavior in failure case would be non-obvious.

If this is a one-off case, you could go via std::shared_ptr, noting that it has an implicit constructor from unique_ptr:

auto ptr = std::unique_ptr<Derived>(
    std::dynamic_pointer_cast<Derived>(readNextThing()).release());

But I think your proposed utility function is clearer. Perhaps use the one from this solution?

ecatmur
  • 152,476
  • 27
  • 293
  • 366