This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Help: auto_ptr conversion confusion


I am sure there are others on this list far more qualified than I to address this question, but here is my understanding:

> 15   auto_ptr<A> a = f();
> 15   auto_ptr<A> a(f());
>
The first of these two initializations is known as 'copy-initialization' the second as 'direct-initialization'. Normally they are the same, but in the case where the left side is an object of class-type, there is a difference.

Copy-initialization requires that the right side be an object of the same type as the left side (or a derived type). In other words, copy-initialization invokes the copy constructor. Recall that auto_ptr's copy constructor is declared
auto_ptr(auto_ptr&);
instead of the more common
auto_ptr(const auto_ptr&);
The absense of the 'const' qualifier is deliberate.

If the rhs of a copy-initialization is not of the correct type the compiler looks for a conversion sequence that would convert the rhs into an object of the correct type. In this case, the rhs not only is not the correct type, it is a value returned from a function call - it is a temporary, or in compiler-speak, an rvalue. Likewise, any conversion sequences that the compiler might try to convert the auto_ptr<B> into an auto_ptr<A> will also result in an rvalue. The language does not allow an rvalue to be bound to a "non-const" reference, so copy-initialization for an auto_ptr will never work if the right hand side is an rvalue. The error messages are not especially clear about what is going on, but they basically say that the compiler can not figure out a way to get the right-hand-side into a form that will allow it to call the copy constructor.

Direct-initialization is simpler. Here the compiler looks at all the constructors, and sees if it can call one of them. The copy constructor we have already dismissed above. The other two constructors of auto_ptr are
template<class Y> auto_ptr(auto_ptr<Y>&)
auto_ptr(auto_ptr_ref<X>)
The first one has the same problem as the normal copy constructor. Although it might appear that the return value of f() should invoke this constructor, the rvalue will not bind to the non-const reference. That leaves the last constructor. Note carefully that its parameter is not a reference, so it can be invoked with an rvalue as an argument.

The compiler finds that it can use auto_ptr<B>::operator auto_ptr_ref<A> to convert the f() return value into a type that can be used to invoke the constructor, so it is happy - so far. At this point it must instantiate and compile the template. This works in this case.

I believe that the compiler is handling this correctly, and the documentation should be changed.

Jack


_________________________________________________________________
Send and receive Hotmail on your mobile device: http://mobile.msn.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]