Will auto_ptr be deprecated in incoming C++ standard?
Should unique_ptr be used for ownership transfer instead of shared_ptr?
If unique_ptr is not in the standard, then do I need to use shared_ptr instead?
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.
Yes, as of today auto_ptr will be deprecated in C++0x and you should use unique_ptr instead. From the latest draft standard (n3035), section D.9
The class template auto_ptr is deprecated. [ Note: The class template unique_ptr (20.9.10) provides a better solution. —end note ]
Until the standard is ratified, it's always possible that the committee will revise this decision although I feel that is unlikely for this decision.
Not only auto_ptr is deprecated in C++11 (D.10, page 1228), it will also be deleted in a future version of C++:
Adopted N4190, and actually removed (not just deprecated) several archaic things from the C++ standard library, including auto_ptr, bind1st/bind2nd, ptr_fun/mem_fun/mem_fun_ref, random_shuffle, and a few more. Those are now all removed from the draft C++17 standard library and will not be part of future portable C++.
Another document about it: Programming Language C++, Library Evolution Working Group - Document N4190, if you want more information.
You can convert any code using auto_ptr automaticaly, by using unique_ptr instead:
Any code using auto_ptr can be mechanically converted to using unique_ptr, with move() inserted whenever auto_ptr was being "copied".
No, it isn't deprecated. It may be, if C++0x ever gets accepted. And it will realistically always be supported. I don't believe that any deprecated feature has ever been dropped from real-world C++ implementations.
Related
I was asked this in an interview. Seems boost library has something called scoped_pointer. Not sure if he asked about that.
Boost does have a scoped_ptr.
Boost Docs
The primary reason to use scoped_ptr rather than auto_ptr is to let readers of your code know that you intend "resource acquisition is initialization" >to be applied only for the current scope, and have no intent to transfer ownership.
A secondary reason to use scoped_ptr is to prevent a later maintenance programmer from adding a function that transfers ownership by returning the auto_ptr, because the maintenance programmer saw auto_ptr, and assumed ownership could safely be transferred.
Think of bool vs int. We all know that under the covers bool is usually just an int. Indeed, some argued against including bool in the C++ standard because of that. But by coding bool rather than int, you tell your readers what your intent is. Same with scoped_ptr; by using it you are signaling intent.
It has been suggested that scoped_ptr is equivalent to std::auto_ptr const. Ed Brey pointed out, however, that reset will not work on a std::auto_ptr const.
The term most probably referred to the c++ smart-pointers category, which provides scoped owner management for pointers.
I was wondering if there are any differences between the boost::shared_ptr and the std::shared_ptr found in the standard <memory> file.
std::shared_ptr is the C++0x form of tr1::shared_ptr, and boost's boost::shared_ptr should behave the same.
However, std::shared_ptr, in an implementation that conforms to C++0x standard, should/might have more convenience behavior on the shared_ptr class, as described in the following links:
Differences between different flavours of shared_ptr
http://en.wikipedia.org/wiki/C%2B%2B0x#General-purpose_smart_pointers
The shared_ptr is a reference-counted pointer that acts as much as possible like a regular C++ data pointer. The TR1 implementation lacked certain pointer features such as aliasing and pointer arithmetic, but the C++0x version will add these.
November 2010 Working Draft of C++0x
Though from a quick cursory glance, I do not see operator+ and similar arithmetic operations on the shared_ptr type.
Occasionally, for fleeting moments, I think auto_ptr is cool. But most of the time I recognize that there are much simpler techniques that make it irrelevant. For example, if I want to have an object freed automatically, even if an exception is thrown, I could new up the object and assign to an auto_ptr. Very cool! But I could have more easily created my object as a local variable, and let the stack take care of it (duh!).
Thus I was not too surprised when I found google C++ coding standards banning the use of auto_ptr. Google states that scoped_ptr should be used instead (if a smart pointer is needed).
I'd like to know if anyone, contrary to my experience, can give a solid reason(s) of when auto_ptr is the best or simplest thing to use. If not, then I suppose I will ban using it myself (following google's lead).
update: For those who expressed concern, no I am not adopting google standards. For example, against google advice, I agree exception-handling should be activated. I also like using preprocessor macros, such as the printable enum I made. It is just the auto_ptr topic that struck me.
update2: It turns out my answer comes from two of the responders below, and a note from Wikipedia. First, Herb Sutter did show a valid use (source-sink idiom and lifetime-linked object composition). Second, there are shops where TR1 and boost are not available or banned and only C++03 is allowed. Third, according to Wikipedia, the C++0x spec is deprecating auto_ptr and replacing it with unique_ptr. So my answer is: use unique_ptr if available to me (on all platforms in consideration) else use auto_ptr for the cases that Sutter depicts.
It's the simplest thing to use when you need a scoped or unique pointer and you are working in a strict C++03 environment with no access to a tr1 implementation or boost.
Herb Sutter can help you out on this one: http://www.drdobbs.com/184403837
While banning auto_ptr seems attractive, but there is one issue:
template <typename T>
some_smart_ptr<T> create();
What will you replace the some_smart_ptr placeholder with ?
The generic answer, shared_ptr, is only worth it if the ownership is truly shared, if the function grants the caller exclusive ownership of the resources, it's misleading at best (and a typical case of premature pessimization as far as I am concerned).
On the other hand, in C++03, no other form of smart pointer can deliver: it's impossible, without move semantics, to provide what we'd like here. auto_ptr or a naked pointer are the two logical contenders. But then a naked pointer exposes you to the risk of leaks if the caller is careless.
With C++0x, unique_ptr advantageously replace auto_ptr in every situation.
std::auto_ptr still has pointer semantics, so automatic (non-pointer) variables aren't a substitute. In particular, std::auto_ptr supports polymorphism and re-assignment. With stack variables you can use references for polymorphism, but references don't allow for re-assignment.
Sometimes std::auto_ptr will do just fine. For example, for implementing a pimpl. True, in the vast majority of cases boost' smart pointer library offers better choices for a smart pointer. But right now std::auto_ptr is a standard solution, whereas boost's smart pointers aren't.
Using auto_ptr as function return value you will enjoy no copiyng overhead and never have memory leak. std::auto_ptr<obj> foo() can be safely called in { foo(); } while obj *foo() cannot. boost::shared_ptr can solve this, but with higher overhead.
Also, some objects can't be created on stack because of memory constraints: thread stacks are relatively small. But boost::scoped_ptr is better in this case since it can't be accidentally released.
Well one reason would be that scoped_ptr is non-copyable, so it's safer to use and harder to make mistakes with. auto_ptr allows transfer of ownership (eg. by passing it another auto_ptr as a constructor parameter). If you need to think things like transferring the ownership, the chances are you're better off with a smart pointer like shared_ptr.
std::auto_ptr lacks const copy constructor, therefore I cannot use it directly in collections. is there some way to have for example vector of std::auto_ptr without using boost pointer collection template?
If you have a C++0x compiler you can use shared_ptr or unique_ptr as appropriate.
There is a good example of correct unique_ptr usage here courtesy of #James McNellis. For a shared_ptr walkthrough look here, courtesy of #D.Shawley. [Upvotes would still be appreciated on those threads, I am sure.]
vector of auto_ptr is always invalid, although Visual C++ v6 disagreed.
No, you just can't have a vector of std::auto_ptr, though there exist many speculations that you can. But if your compiler supports C++0x, you can use std::unique_ptr, which is the new alternative of the deprecated auto pointer which, quote from the new standard, provides a superior alternative. See also this thread
auto_ptr is designed for auto deletion when a variable leaves scope. You don't want to use it in a collection, instead as mentioned above you want to use something like shared_ptr.
Example of auto_ptr's typical use:
void foo()
{
auto_ptr<int> bar = auto_ptr<int>(new int);
...
return; //memory held by auto_ptr is automatically deleted
}
Anything beyond this use is potentially dangerous and/or broken if you are not sure of the special semantics of auto_ptr. (Edit: clarify based on Armen's comment)
What is the best way to indicate that an object wants to take ownership of another object? So far, I've been using a std::auto_ptr in the public interface, so the client knows that the interface wants to take ownership of the passed object.
However, the latest GCC tells me auto_ptr is deprecated, so I wonder what is recommended? boost::interprocess::unique_pointer looks like a good candidate, but is this really the best solution out there?
boost::interprocess is a library for interprocess communication, so I wouldn't use it for different purposes.
As discussed on this forum:
http://objectmix.com/c/113487-std-auto_ptr-deprecated.html
std::auto_ptr will be declared deprecated in the next version of the standard, where it will be recommended the usage of std::unique_ptr, which requires rvalue references and move semantics to be implemented (that's a fairly complicated feature).
Until the new standard is released, I would simply try to disable the warning if possible, or ignore it, for maximum portability.
If you want to already switch to the next language standard, it is possible since rvalue references have been implemented (see http://russ.yanofsky.org/rref/), so also std::unique_ptr should be supported.
On of the advantages of the new semantics is that you can pass to the move constructor also a temporary or any rvalue; in other cases, this allows avoiding to copy (for instance) objects contained inside a std::vector (during reallocation) before destroying the original ones.
std::unique_ptr is indeed the new recommended way. With C++0x containers will become move-aware, meaning that they can handle types which are movable correctly (i.e., std::vector<std::auto_ptr<x> > does not work, but std::vector<std::unique_ptr<x>> will).
For boost, the boost::interprocess containers already support movable types, where boost::interprocess::unique_ptr is one of them. They resemble movable types in pre C++0x by using some of the "normal" boost-template wizardry, and use r-value references where they are supported.
I didn't know about the auto_ptr dedicated deprecation, though, but I've not followed the new standard evolution closely.
(edit) The implementation of boost::interprocess::unique_ptr is indeed not a "public" smart-pointer like boost::shared_ptr or boost::scoped_ptr, but it is (see boost.interprocess's site) not just for shared-memory, but can also be used for general-purpose.
However, I'm quite sure that if GCC deprecates the auto_ptr template, they already provide their own unique_ptr implementation (not much use to deprecate if you not have a viable alternative yet).
However, that all being said, if you're working on a C++0x platform, use unique_ptr, available from the compiler's lib, if not, stick with auto_ptr.
I agree where possible you should use types where the compiler assists in ownership transfer.
Where you don't have that choice of data types and are passing raw pointers, I follow the Taligent programming guidelines of naming methods which relinquish ownership as orphanBlah and parameters which take ownership as adoptBlah.
std::auto_ptr implements ownership passing on copy and assignment, so there is nothing special you should do about it:
std::auto_ptr< T > p = somePtr; // not p owns object, referenced by somePtr
std::auto_ptr< T > q = myObj.GetAutoPtr(); // not q owns object referenced by auto_ptr in myObj
But passing object ownership is not a good design practice, it conducts to leaks and object lifetime relative errors.
I don't remember std::auto_ptr being deprecated.
Anybody have a link to the appropriate standards meeting where they discuss this?
A quick google found this:
http://objectmix.com/c/113487-std-auto_ptr-deprecated.html
>> In fact the latest publicly available draft lists auto_ptr in appendix
>> D, meaning that there is clear intent to formally deprecate it in the
>> next revision of C++. A new class named unique_ptr is going to provide
>> a replacement for auto_ptr, the main difference being that unique_ptr
>> uses rvalue-references instead of voodoo magic to properly achieve
>> move semantic.
>
> Is a reference implementation available? Is it too early to start using it?
>
In order to use unique_ptr you need first to have a compiler which
properly supports rvalue references. These can be hard to find nowadays,
as the feature has not yet been standardized, although the situation is
quickly improving. For example GCC has very recently added the feature
in v4.3 (http://gcc.gnu.org/gcc-4.3/cxx0x_status.html). If you are lucky
enough to have one of those compilers, most probably they already ship a
version of unique_ptr (it's a sort of benchmark for the feature, you
know). In any case, you can find reference implementations on the
internet by just googling unique_ptr.
So it looks like their are moves to deprecate auto_ptr in favor of unique_ptr (which has the same semantics). But it needs a compiler that supports the proposed new features in the upcoming version of C++.
But there is still another meeting and thus vote to come so things could change before the standard is made concrete.