简体   繁体   中英

auto_ptr vs unique_ptr in containers & algorithms

I understand auto_ptr has screwed up copy semantics and therefore is not safe for use in containers since copying one auto_ptr to another will make the source = NULL pointer (isn't this like move semantics anyway??). But then again, unique_ptr cannot be copied at all and can only transfer ownership. So, how is unique_ptr usable in containers and algorithms that need to use copy operations to copy and re-arrange elements?

There is an in-depth explanation of why auto_ptr is dangerous, while unique_ptr is not: N1856 : Why deprecate auto_ptr?

The main argument is that in generic code, something that has the syntax of a copy, should be a copy, not a move:

template <class It>
void sort(It first, It last)
{
    // ...
    value_type pivot_element = *mid_point;
    // ...
}

In the above example, the generic code is highly likely to have logic that demands that pivot_element and *mid_point be equivalent after the copy construction shown. This may or may not be generic code in the std::lib . It might be generic code you have written.

When value_type turns out to be a std::auto_ptr<T> , then the above code compiles, but the assumption that pivot_element == *mid_point fails. A run-time error follows.

When value_type turns out to be a std::unique_ptr<T> , then the above code fails at compile-time (because you can't copy a std::unique_ptr<T> ). Thus use of std::unique_ptr<T> in preference to std::auto_ptr<T> effectively turns run time errors into compile-time errors.

Now it is also true that within the std::lib , algorithms such as sort have been respecified such that they are not allowed to copy value_type . So it actually is safe to sort a sequence of auto_ptr<T> now (using std::sort ). However std::unique_ptr<T> completely replaces the functionality of auto_ptr<T> , and auto_ptr<T> is still dangerous to use in generic code that does use copying ( unique_ptr<T> fails to compile when used in such generic code).

So unique_ptr is safer to use than auto_ptr because it refuses to compile when used with generic code that copies.

They don't need to use copy operations anymore in the vast majority of cases. Move-only types like unique_ptr are first-class citizens. That's why move semantics is such a great improvement for both performance and correctness.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM