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?
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?
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 ;-)
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).
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.
auto_ptr
is fundamentally broken, and rvalue references aren't. It's just that simple.
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.
© 2022 - 2024 — McMap. All rights reserved.
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-study – Questionnaireshared_ptr
s is surely no solution to any problem. – Claire