std::auto_ptr to std::unique_ptr

C++C++11Smart PointersAuto PtrUnique Ptr

C++ Problem Overview


With the new standard coming (and parts already available in some compilers), the new type std::unique_ptr is supposed to be a replacement for std::auto_ptr.

Does their usage exactly overlap (so I can do a global find/replace on my code (not that I would do this, but if I did)) or should I be aware of some differences that are not apparent from reading the documentation?

Also if it is a direct replacement, why give it a new name rather than just improve the std::auto_ptr?

C++ Solutions


Solution 1 - C++

You cannot do a global find/replace because you can copy an auto_ptr (with known consequences), but a unique_ptr can only be moved. Anything that looks like

std::auto_ptr<int> p(new int);
std::auto_ptr<int> p2 = p; 

will have to become at least like this

std::unique_ptr<int> p(new int);
std::unique_ptr<int> p2 = std::move(p);

As for other differences, unique_ptr can handle arrays correctly (it will call delete[], while auto_ptr will attempt to call delete.

Solution 2 - C++

std::auto_ptr and std::unique_ptr are incompatible in someways and a drop in replacement in others. So, no find/replace isn't good enough. However, after a find/replace working through the compile errors should fix everything except weird corner cases. Most of the compile errors will require adding a std::move.

  • Function scope variable:
    100% compatible, as long as you don't pass it by value to another function.
  • Return type:
    not 100% compatible but 99% compatible doesn't seem wrong.
  • Function parameter by value:
    100% compatible with one caveat, unique_ptrs must be passed through a std::move call. This one is simple as the compiler will complain if you don't get it right.
  • Function parameter by reference:
    100% compatible.
  • Class member variable:
    This one is tricky. std::auto_ptrs copy semantics are evil. If the class disallows copying then std::unique_ptr is a drop in replacement. However, if you tried to give the class reasonable copy semantics, you'll need to change the std::auto_ptr handling code. This is simple as the compiler will complain if you don't get it right. If you allowed copying of a class with a std::auto_ptr member without any special code, then shame on you and good luck.

In summary, std::unique_ptr is an unbroken std::auto_ptr. It disallows at compile time behaviors that were often errors when using a std::auto_ptr. So if you used std::auto_ptr with the care it needed, switching to std::unique_ptr should be simple. If you relied on std::auto_ptr's odd behavior, then you need to refactor your code anyway.

Solution 3 - C++

AFAIK, unique_ptr is not a direct replacement. The major flaw that it fixes is the implicit transfer of ownership.

std::auto_ptr<int> a(new int(10)), b;
b = a; //implicitly transfers ownership

std::unique_ptr<int> a(new int(10)), b;
b = std::move(a); //ownership must be transferred explicitly

On the other hand, unique_ptr will have completely new capabilities: they can be stored in containers.

Solution 4 - C++

Herb Sutter has a nice explanation on GotW #89:

> What’s the deal with auto_ptr? auto_ptr is most charitably characterized as a valiant attempt to create a unique_ptr before C++ > had move semantics. auto_ptr is now deprecated, and should not be used > in new code. > > If you have auto_ptr in an existing code base, when you get a chance > try doing a global search-and-replace of auto_ptr to unique_ptr; the > vast majority of uses will work the same, and it might expose (as a > compile-time error) or fix (silently) a bug or two you didn't know you > had.

In other words, while a global search-and-replace may "break" your code temporarily, you should do it anyway: It may take some time to fix the compile errors, but will save you a lot more trouble in the long run.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMartin YorkView Question on Stackoverflow
Solution 1 - C++CubbiView Answer on Stackoverflow
Solution 2 - C++deft_codeView Answer on Stackoverflow
Solution 3 - C++UncleBensView Answer on Stackoverflow
Solution 4 - C++ValarDohaerisView Answer on Stackoverflow