Search code examples
c++c++11inheritanceunique-ptrc++20

How to return reference of unique_ptr<Derived> from unique_ptr<Base>?


I work with unique_ptr on derived structs, and I return references to maintain ownership and keep minimal overhead.

Basically, I want a get function to turn unique_ptr<Base> into unique_ptr<Derived>&.

  • I can't use dynamic_pointer_cast as it copies and fails : no matching function for call to 'dynamic_pointer_cast<Derived>(std::unique_ptr<Base>&)'
  • I can't use std::move or release from obj, as it is the source of truth of the program.

Do you guys see any alternative? The shared_ptr version works OK btw, is it the only path?

Thanks in advance for your input. JD

#include <memory>

struct Base {

};
struct Derived : public Base {
    float position;
    Derived(float position_) : position(position_) {}
};

//SOURCE OF TRUTH
std::unique_ptr<Base> obj; 


//retreive from obj
template<typename T>
std::unique_ptr<T>& get() {
    std::unique_ptr<Base> &p = obj;
    return std::dynamic_pointer_cast<T>(p); //<-- pb: fails because it copies...
}


int main() {
    //storing
    obj = std::make_unique<Derived>(10.0f);

    // ...

    //retrieving
    std::unique_ptr<Derived>& p = get<Derived>();   
    return 0;
}

Solution

  • You can still just do a regular dynamic_cast with the raw pointer, ie.:

    template<typename T>
    T* get() {
        std::unique_ptr<Base> &p = obj;
        return dynamic_cast<T*>(p.get());
    }
    

    Semanticly that is ok as raw pointer is taken to mean non-owning.