converting a auto_ptr to a shared_ptr

3.6k Views Asked by At

How can I change an std::auto_ptr to a boost::shared_ptr? Here are my restrictions: 1. I am using an API class, lets call it only_auto that returns these pointers 2. I need to use the call in auto_only 3. My semantics involves sharing so I do need to use a shared_ptr) 4. In class only_auto operator = is private to prevent coping 5. Also a only_auto object must be made by a cloning call std::auto_ptr creat_only_auto();

I know of template explicit shared_ptr(std::auto_ptr & r); but how do I use it in this scenario?

A super-simplified code example:

    #include <iostream>
    #include <memory>
    #include <boost/shared_ptr.hpp>

    using namespace std;

    class only_auto
    {
      public:
      static auto_ptr<only_auto> create_only_auto();
      void func1();
      void func2();
      //and lots more functionality

      private:
      only_auto& operator = (const only_auto& src);
    };

    class sharing_is_good : public only_auto
    {
      static boost::shared_ptr<only_auto> create_only_auto()
      {
        return boost::shared_ptr (only_auto::create_only_auto()); //not the correct call but ...
      }

    };

    int main ()
    {
       sharing_is_good x;

       x.func1();
    }
3

There are 3 best solutions below

0
On

3. My semantics involves sharing so I do need to use a shared_ptr)

Most valid uses of auto_ptr are source compatible with std::unique_ptr, so you might want to look at converting to that. If everything builds okay then you're safe. (You might want to move to using a typedef if you're not already, so you can easily change the type in the future.) If you have a compile error you may have a bug in your code where you were previously using an invalidated auto_ptr.

I think you should only look to moving to std::shared_ptr after you've validated things with unique_ptr and you see you really do need shared ownership (often you can just use unique ownership and non-owning pointers).

1
On

The shared_ptr constructor is declared as:

template<class Other>
shared_ptr(auto_ptr<Other>& ap);

Note that it takes a non-const lvalue reference. It does this so that it can correcly release the auto_ptr's ownership of the object.

Because it takes a non-const lvalue reference, you cannot call this member function with an rvalue, which is what you are trying to do:

return boost::shared_ptr(only_auto::create_only_auto());

You'll need to store the result of only_auto::create_only_auto() in a variable, then pass that variable to the shared_ptr constructor:

std::auto_ptr<only_auto> p(only_auto::create_only_auto());
return boost::shared_ptr<only_auto>(p);
0
On

I think

return boost::shared_ptr<only_auto>(only_auto::create_only_auto().release());

should do the trick