Is auto_ptr deprecated?
UPDATE: This answer was written in 2010 and as anticipated std::auto_ptr
has been deprecated. The advice is entirely valid.
In C++0x std::auto_ptr
will be deprecated in favor of std::unique_ptr
. The choice of smart pointer will depend on your use case and your requirements, with std::unique_ptr
with move semantics for single ownership that can be used inside containers (using move semantics) and std::shared_ptr
when ownership is shared.
You should try to use the smart pointer that best fits the situation, choosing the correct pointer type provides other programmers with insight into your design.
Why is auto_ptr being deprecated?
The direct replacement for auto_ptr
(or the closest thing to one anyway) is unique_ptr
. As far as the "problem" goes, it's pretty simple: auto_ptr
transfers ownership when it's assigned. unique_ptr
also transfers ownership, but thanks to codification of move semantics and the magic of rvalue references, it can do so considerably more naturally. It also "fits" with the rest of the standard library considerably better (though, in fairness, some of that is thanks to the rest of the library changing to accommodate move semantics instead of always requiring copying).
The change in name is also (IMO) a welcome one -- auto_ptr
doesn't really tell you much about what it attempts to automate, whereas unique_ptr
is a fairly reasonable (if terse) description of what's provided.
Error : ‘templateclass class std::auto_ptr’ is deprecated
If you read some books of Scott Meyers, he strongly recommends not to use auto_ptr
. Actually, new compilers may restrict it's usage because of lots of possible problems with it when using auto_ptr
in STL containers, etc.
Instead, you should use std::unique_ptr
if you don't want more that one copy of the object, and std::shared_ptr
if you need to copy the pointer.
how to resolve g++ warning with -std=c++11: ‘auto_ptr’ is deprecated
You may use std::unique_ptr
instead of std::auto_ptr
And if you copied auto_ptr
, you have to std::move
the unique_ptr
.
C++ std:.auto_ptr or std::unique_ptr (to support multiple compilers, even old C++03 compilers)?
As you noted, std::auto_ptr<> has been deprecated in C++11
(Reference).
Moving to c++11 std::unique_ptr<> is the right way, as also stated by Herb Sutter in
GotW89:
- What’s the deal with auto_ptr?
auto_ptr is most charitably characterized as a valiant attempt to create a unique_ptr before C++ had move semantics. auto_ptr is now deprecated, and should not be used in new code.
If you have auto_ptr in an existing code base, when you get a chance try doing a global search-and-replace of auto_ptr to unique_ptr; the vast majority of uses will work the same, and it might expose (as a compile-time error) or fix (silently) a bug or two you didn’t know you had.
Please also note that C++17 is going to remove std::auto_ptr.
I think there may be different ways of solving your problem, the "right" one also depends on how your actual code is written.
A few options are:
Option 1
Use boost::unique_ptr
Option 2
Conditionally use auto_ptr or unique_ptr based on __cplusplus.
class Myclass {
#if __cplusplus < 201103L
std::auto_ptr m_ptr;
#else
std::unique_ptr m_ptr;
#endif
...
This will be scattered in every place where you reference auto_ptr, I don't really like it.
May be look less awkward if all your references to std::auto_ptr are already typedef'ed (just conditionally change the typedef).
Option 3
Conditionally use using and aliasing to "define" auto_ptr (and reference it without std:: namespace).
#if __cplusplus < 201103L
using std::auto_ptr;
#else
template
using auto_ptr = std::unique_ptr;
#endif
Drawback: you keep using "auto_ptr", but in c++11 it means std::unique_ptr.
Really confusing...
Option 3.1
Probably slightly better than option 2:
reverse using aliases and prefer unique_ptr name.
Option 4
Wrap the std:: smart pointer (conditionally auto_ptr or unique_ptr) in your own defined template smart pointer class.
This may be cumbersome and requires search and replacement of all auto_ptr references with your new class.
Other dirty options
Other options involve definitions inside the std:: namespace, which I think is prohibited by the standard,
or using preprocessor #define to ...ehm... "rename" unique_ptr to auto_ptr just for old C++03 compilers.
no warning: ‘auto_ptr’ is deprecated only when auto_ptr used just once
This a known bug of GCC 33911, with status NEW
.
Function taking a std::auto_ptrBase that can accept std::auto_ptrDerived
You can cast without ambiguity:
function(static_cast<std::auto_ptr<Base> >(derivedPtr));
Be aware that for this to work, Base
must have a virtual destructor. Otherwise the code has undefined behavior.
The reason for the ambiguity is as Arne says in his answer -- it's not obvious to the caller whether function
takes a value or a reference, and therefore it's not obvious to the caller whether their auto_ptr
will be released or not by making the call, and if it is released whether it's converted to a type that can correctly delete
the pointer. The ambiguous conversion AFAIK is there to stop you writing such difficult code. By casting, you make it explicit in the calling code that derivedPtr
is released.
Related Topics
Pass by Pointer & Pass by Reference
Is 1.0 a Valid Output from Std::Generate_Canonical
Printing Double Without Losing Precision
How to Create Std::Array with Initialization List Without Providing Size Directly
Is Writing to &Str[0] Buffer (Of a Std:String) Well-Defined Behaviour in C++11
C++ Read File Line by Line Then Split Each Line Using the Delimiter
Looking for 16-Bit X86 Compiler
Parameter Name Omitted, C++ VS C
Why the Libc++ Std::Vector Internally Keeps Three Pointers Instead of One Pointer and Two Sizes
How to Easily Make Std::Cout Thread-Safe
Is There an Equivalent to Winapi's Max_Path Under Linux/Unix
Boost::Property_Tree Xml Pretty Printing
Does Delete Work with Pointers to Base Class
Vary Range of Uniform_Int_Distribution
C++: How to Get Fprintf Results as a Std::String W/O Sprintf