
Howard Hinnant wrote:
On Dec 22, 2008, at 9:10 PM, Michael Marcin wrote:
Mathias Gaunard wrote:
Sid Sacek wrote:
1) When would I choose unique_ptr<> over auto_ptr<> ? Always. auto_ptr is deprecated and is dangerous. unique_ptr, for example, perfectly works with containers.
With containers written to support unique_ptr or with any Container as defined by the standard's concept?
It will work with containers written to support unique_ptr (or move-only types). std-defined C++0X containers will support move-only types. std-defined C++03 containers do not.
The basic advance of unique_ptr over auto_ptr is that with unique_ptr if things compile, they will work. With auto_ptr things might compile but produce run time errors. So if your container<unique_ptr<A>> compiles, then you can use it with confidence. But it will likely not compile if it hasn't been designed to work with move-only types.
This state of affairs is not nearly as mysterious as it sounds. I'd like to lift the veil a little. The reason auto_ptr is prone to produce run time errors is because generic code is often written which looks like:
template <class T> void foo(T t) { T t2 = t; assert(t2 == t); }
The generic code may not (probably does not) have the explicit assert as shown above. But its logic may assume that when it makes a copy, either via construction or assignment, that the source and target are equivalent after the copy. When T turns out to be an auto_ptr, then this assumption is silently broken, and thus the logic of the generic algorithm is broken. When T turns out to be a unique_ptr, the copy won't compile. Thus the breakage with unique_ptr happens at compile time, whereas the breakage with auto_ptr occurs at run time.
A generic algorithm designed to work with move-only types will avoid logic that demands copies. If it needs to, it might /move/ objects around instead of copy them around:
template <class T> void foo(T t) { T t2 = std::move(t); // no assumption here on the value of t }
Sure makes sense but since we don't yet have a generic implementation of move to use no generic algorithms can really rely on it, right? This leaves me to believe the only real uses of unique_ptr right now in C++03 are 1. a more descriptive name than auto_ptr or scoped_ptr for some use cases 2. custom deleter support -- Michael Marcin