tags:

views:

302

answers:

2

auto_ptr_ref documentation here says this

This is an instrumental class to allow certain conversions that allow auto_ptr objects to be passed to and returned from functions.

Can somebody explain how auto_ptr_ref helps in achieving this. I just want to understand the auto_ptr class and its internals

+8  A: 

It is rather confusing. Basically, auto_ptr_ref exists because the auto_ptr copy constructor isn't really a copy constructor in the standard sense of the word.

Copy constructors typically have a signature that looks like this:

X(const X &b);

The auto_ptr copy constructor as a signature that looks like this:

X(X &b)

This is because auto_ptr needs to modify the object being copied from in order to set its pointer to 0 to facilitate the ownership semantics of auto_ptr.

Sometimes, temporaries cannot match a copy constructor that doesn't declare its argument const. This is where auto_ptr_ref comes in. The compiler won't be able to call the non-const version of the copy constructor, but it can call the conversion operator. The conversion operator creates an auto_ptr_ref object that's just sort of a temporary holder for the pointer. The auto_ptr constructor or operator = is called with the auto_ptr_ref argument.

If you notice, the conversion operator in auto_ptr that automatically converts to an auto_ptr_ref does a release on the source auto_ptr, just like the copy constructor does.

It's kind of a weird little dance that happens behind the scenes because auto_ptr modifies the thing being copied from.

Random related tanget about C++0x and unique_ptr

In C++0x, auto_ptr is deprecated in favor of unique_ptr. unique_ptr doesn't even have a copy constructor and uses the new 'move constructor' which is explicit about the fact that it will modify the object being moved from and leave it in a useless (but still valid) state. Temporaries (aka rvalues) are explicitly always allowed to be arguments to a move constructor.

The move constructor in C++0x has a number of other big benefits. It enables the standard STL containers to store unique_ptrs and do the right thing, as opposed to how auto_ptrs cannot be. It also mostly eliminates the need for the 'swap' function as the whole purpose of the swap function is usually to be a move constructor or move assignment operator that never throws.

Which is the other expectation. The move constructor and move assignment operator (much like a destructor) are never supposed to throw.

Omnifarious
Doesn't eliminate the need for swap, but does replace uses of swap for moving.
Roger Pate
@Roger Pate, Oh, yeah, you're right. For example, ideally you would copy a vector, try to add something to the copy, and swap the original for the copy. Though in most of those cases you could just as easily move the copy into the original using move assignment.
Omnifarious
@Roger: Maybe I'm mis-understanding, but it does remove the need for custom `swap` functions. It replaces it with the requirement to write rvalue-functions which we would do anyway (and looks like they can be defaulted), so I'd say really we're being saved a function.) Shameless self-plug: http://stackoverflow.com/questions/2078515/why-arent-there-compiler-generated-swap-methods-in-c0x/2078987#2078987
GMan
@GMan: Maybe I'm misunderstanding, but it doesn't say custom swap functions, and I interpreted it as "any time you'd want to use swap" (instead of implement), such as for algorithms like sort.
Roger Pate
@Roger Pate, I was talking about custom swap functions. And I agreed with you without thinking it through carefully. Once you have a move constructor it's possible to implement an efficient generic swap operation.
Omnifarious
A: 

I just found a very good link and a name for this technique "Move Constructors" or "Colvin-Gibbons trick"

http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Move_Constructor

Yogesh Arora
That is a most excellent article.
Omnifarious