std::move vs std::auto_ptr?
Asked Answered
A

5

5

What can I do with 'move' (r-value references) in C++11 what I can't with std::auto_ptr? (As I understand they are different implementations of one idea.)

And old question again: is std::auto_ptr so bad component?

Accuracy answered 11/12, 2011 at 16:27 Comment(6)
Regardless of the relative badness of auto_ptr vs. unique_ptr, I personally think shared pointers are the better bet. "it can be better to simplify the contract, instead of attempting to enforce it verbatim with the type system". I break it down a bit in this article: hostilefork.com/2009/07/10/smart-pointer-casting-studyQuestionnaire
recommended watchProt
They are definitely not different implementations of the same idea. You are probably mixing things here. They are somehow related, but as it stands this statement is wrong.Claire
@HostileFork They are not better if the objects don't need to be (or even worse, should not be) shared. Use the right tool for the right job. Spamming everything with a mess of shared_ptrs is surely no solution to any problem.Claire
@ChristianRau One should match a solution to the problem, naturally. But if you can rephrase a problem such that it doesn't require uniqueness you simplify the contract, and that can be helpful. This is the success of languages like Java. Programming is hard enough without making people follow a "hot potato", so don't do it unless it represents a resource that must be forced unique for a truly fundamental reason. See article.Questionnaire
@HostileFork Don't use shared_ptr where unique_ptr will do. This is even more important when you're transitioning to multithreaded code.Willner
L
16

C++98/03 has no notion of truly "movable" classes. auto_ptr is a class with transfer-on-copy-semantics, i.e. when you make a copy, the content of the original changes (note the copy constructor with non-const argument!). This is Bad. Such a class cannot be used in the standard containers.

C++11 introduces the concept of truly movable classes thanks the the newly added notion of rvalue references. The new unique_ptr, which replaces auto_ptr entirely, is no longer copyable at all, but instead it is movable. All standard containers have been updated to attempt to move objects if possible, so it is now possible to store move-only objects in standard containers. Other examples of object which are only movable but not copyable are mutexes, locks, threads and iostreams.

To hammer in the point, compare a hypothetical, broken, C++98 piece of code with the corresponding C++11 code:

std::auto_ptr<Foo> p1(new Foo);
std::vector< std::auto_ptr<Foo> > v1;
//v1.push_back(p1);  // eeww, what is the state of p1 now? ERROR

std::unique_ptr<Foo> p2(new Foo);
std::vector<std::unique_ptr<Foo>> v2;
//v2.push_back(p2);          // Error, copying is simply not allowed
v2.push_back(std::move(p2)); // explicit; mustn't read p2 after moving it
v2.emplace_back(new Foo);    // even better ;-)
Lues answered 11/12, 2011 at 16:31 Comment(0)
L
5

The problem with std::auto_ptr is that it has copy operations which works like move operations. Therefore algorithms which work with copy operations can work on auto_ptr, but they don't behave as expected, since copied from objects have changed. As such auto_ptr can't be used with STL containers, however code which tries to do so will compile, but fail to work at runtime.

std::unique_ptr on the other hand doesn't have copy operations, but is only moveable instead. Therefore algorithms which copy std::unique_ptr will fail to compile when they should operate on std::unique_ptr. If something uses move operations, it doesn't expect the source of the move operation to remain the same, so no confusion there.

So basically it comes down to the operations working as is expected for a C++ object (or not).

Lamelliform answered 11/12, 2011 at 16:35 Comment(0)
O
2

One big difference is rvalue references (and assorted move optimizations) are automatically inferred/deducted from the calling context, whereas you need to create auto_ptr's manually at the call site.

Otter answered 11/12, 2011 at 16:30 Comment(0)
A
2

auto_ptr is fundamentally broken, and rvalue references aren't. It's just that simple.

Aficionado answered 11/12, 2011 at 16:32 Comment(3)
I suppose a more diplomatic way of saying it is that "auto_ptr implements non-standard semantics which make its usefulness rather limited".Lues
<strike>That sounds like Christianity.</strike> (yes, we want to be politically correct). Why do you not explain what you claim is the state of affairs?Cuyp
@Johannes: He asked if it was bad. The answer to that is that it is.Aficionado
A
2

What can I do with 'move' (r-value references) in C++11 what I can't with std::auto_ptr?

The very most important benefit of move, unique_ptr, etc, over auto_ptr is what you can't do, but can with auto_ptr.

This link explains the rationale to the committee for deprecating auto_ptr. It contains this conclusion:

Conclusion:

One should not move from lvalues using copy syntax. Other syntax for moving should be used instead. Otherwise generic code is likely to initiate a move when a copy was intended.

For details on how this conclusion was reached, read the link.

Antistrophe answered 11/12, 2011 at 17:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.