I am learning about smart pointers (std::auto_ptr
) and just read here and here that smart pointers (std::auto_ptr
) should not be put in containers
For classes that have an auto ptr data member, I always have a clone method that returns a new auto ptr. I then implement an assignment method and copy constructor that call the clone method (and never the default assignment operator of auto ptr). This way you can safely use the class in STL containers.
theoretically you can use std::auto_ptr
with STL containers if you completely understand their internal implementation and don't do anything that can lose auto_ptr ownership, but practically it's much more safe to use containers with raw ptrs.
"In reality, how often does this happen?" - is very dangerous question by itself. first of all, STL - it's not a single standard implementation, there're many. Each one can implement containers in different ways, so your highly tuned code to avoid all "auto_ptr in containers" mines can burst switching to another STL implementation. Also, your code maintenance will be highly complicated, any correctly looking change to your code can break your program. how can you remember that or force others maintainers to remember? putting warnings in any place where such changes can occur? impossible.
so, conclusion: it's just a bad idea that brings nothing but headache
Yes, you really can't use std::auto_ptr
with standard containers. std::auto_ptr
copies aren't equivalent, and because standard containers (and algorithms) are allowed to copy their elements at will this screws things up. That is, the operation of copying a std::auto_ptr
has a meaning other than a mere copy of an object: it means transferring an ownership.
Your options are:
The problem you are referring to concerns auto_ptr since it moves ownership on copy. shared_ptr and unique_ptr work just fine with containers.
Any type that you use with a standard container template must conform with the requirements for that container. In particular, the type must satisfy the requirements for CopyConstructible and Assignable types.
Many smart pointers do satisfy these requirements and may be used with standard containers but std::auto_ptr
is not one of them because copies of std::auto_ptr
are not equivalent to the source that they were created or assigned from.
Although some implementations of standard container may work with auto_ptr
in some situations it is dangerous to rely on such implementation details.