Search code examples
c++shared-ptrauto-ptr

convert shared_ptr to auto_ptr?


I need to obtain auto_ptr from shared_ptr in my code. I can do reverse operation - convert auto_ptr to shared_ptr as shared_ptr has such constructor:

template<class Y> explicit shared_ptr(std::auto_ptr<Y> & r);

Can I convert shared_ptr to auto_ptr? Or it is impossible by design?


Solution

  • A shared pointer can be shared by many things, you can't just take it from them all somehow. This is elaborated by Artyom and peoro.

    One approach is to make a temporary auto_ptr, and release it from handling the pointer at the end of the scope. dalle outlines a first approach, but this suffers from lack of exception-safety (might accidentally delete), and it cannot protect you from accidentally passing it to a function that's going to transfer ownership (where the delete falls out of our hands).

    We can make our own wrapper to avoid this, though:

    template <typename T>
    class auto_ptr_facade
    {
    public:   
        auto_ptr_facade(shared_ptr<T> ptr) :
        mPtr(ptr),
        mAuto(ptr.get())
        {}
    
        ~auto_ptr_facade()
        {
            // doesn't actually have ownership
            mAuto.release();
        }
    
        // only expose as const, cannot be transferred
        const auto_ptr<T>& get() const
        {
             return mAuto;
        }
    
        operator const auto_ptr<T>&() const
        {
             return get();
        }
    
    private:
        auto_ptr_facade(const auto_ptr_facade&);
        auto_ptr_facade& operator=(const auto_ptr_facade&);
    
        shared_ptr<T> mPtr;
        auto_ptr<T> mAuto;
    };
    

    Now you can treat a shared_ptr like a const auto_ptr, in a scope:

    template <typename T>
    void foo(shared_ptr<T> ptr)
    {
        auto_ptr_facade<T> a(ptr);
    
        // use a
    }