|
Boost : |
Subject: Re: [boost] [unique_ptr] So how is it used differently?
From: Howard Hinnant (howard.hinnant_at_[hidden])
Date: 2008-12-22 22:23:11
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
}
-Howard
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk