Why is it wrong to use std::auto_ptr<> with standard containers?

C++StlRaiiAuto PtrC++ Faq

C++ Problem Overview


Why is it wrong to use std::auto_ptr<> with standard containers?

C++ Solutions


Solution 1 - C++

The C++ Standard says that an STL element must be "copy-constructible" and "assignable." In other words, an element must be able to be assigned or copied and the two elements are logically independent. std::auto_ptr does not fulfill this requirement.

Take for example this code:

class X
{
};

std::vector<std::auto_ptr<X> > vecX;
vecX.push_back(new X);

std::auto_ptr<X> pX = vecX[0];  // vecX[0] is assigned NULL.

To overcome this limitation, you should use the std::unique_ptr, std::shared_ptr or std::weak_ptr smart pointers or the boost equivalents if you don't have C++11. Here is the boost library documentation for these smart pointers.

Solution 2 - C++

The copy semantics of auto_ptr are not compatible with the containers.

Specifically, copying one auto_ptr to another does not create two equal objects since one has lost its ownership of the pointer.

More specifically, copying an auto_ptr causes one of the copies to let go of the pointer. Which of these remains in the container is not defined. Therefore, you can randomly lose access to pointers if you store auto_ptrs in the containers.

Solution 3 - C++

Two super excellent articles on the subject:

Solution 4 - C++

The STL containers need to be able to copy the items you store in them, and are designed to expect the original and the copy to be equivalent. auto pointer objects have a completely different contract, whereby copying creates a transfer of ownership. This means that containers of auto_ptr will exhibit strange behaviour, depending on usage.

There is a detailed description of what can go wrong in Effective STL (Scott Meyers) item 8 and also a not-so-detailed description in Effective C++ (Scott Meyers) item 13.

Solution 5 - C++

STL containers store copies of contained items. When an auto_ptr is copied, it sets the old ptr to null. Many container methods are broken by this behavior.

Solution 6 - C++

C++03 Standard (ISO-IEC 14882-2003) says in clause 20.4.5 paragraph 3: > [...] > [Note: [...] > auto_ptr does not meet the CopyConstructible and Assignable requirements for Standard Library > container elements and thus instantiating a Standard Library container > with an auto_ptr results in undefined behavior. — end note]

C++11 Standard (ISO-IEC 14882-2011) says in appendix D.10.1 paragraph 3: > [...] > Note: [...] Instances of auto_ptr meet the requirements of > MoveConstructible and MoveAssignable, but do not meet the requirements > of CopyConstructible and CopyAssignable. — end note ]

C++14 Standard (ISO-IEC 14882-2014) says in appendix C.4.2 Annex D: compatibility features:

> Change: The class templates auto_ptr, unary_function, and binary_function, the function templates random_shuffle, and the > function templates (and their return types) ptr_fun, mem_fun, > mem_fun_ref, bind1st, and bind2nd are not defined.
> Rationale: Superseded by new features.
> Effect on original feature: Valid C ++ 2014 code that uses these class templates and function templates may fail to compile in this > International Standard.

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
QuestionUhallView Question on Stackoverflow
Solution 1 - C++KevinView Answer on Stackoverflow
Solution 2 - C++Frank KruegerView Answer on Stackoverflow
Solution 3 - C++LazerView Answer on Stackoverflow
Solution 4 - C++Garth GilmourView Answer on Stackoverflow
Solution 5 - C++Dustin GetzView Answer on Stackoverflow
Solution 6 - C++Alex BitekView Answer on Stackoverflow