Boost logo

Boost :

From: Rani Sharoni (rani_sharoni_at_[hidden])
Date: 2004-02-09 04:08:54


David Abrahams wrote:
> "Rani Sharoni" <rani_sharoni_at_[hidden]> writes:
>> The problem with reference binding using conversion
>> operator/constructor(i.e. X const& r = X()) is addressed in active
>> DR #291 (see Mr. Adamczyk note)
>
> I'm not really sure what to make of that text.

I'll try to elaborate on that. 8.3.5/5 states that when binding class
r-value to a const reference there is a possibility to introduce additional
const temporary from the r-value and then bind it to the reference (which
might, recursively, introduce, yet additional temporary).

The question is how to construct this additional const temporary which,
according to TC1 #171, is an r-value. Now we are back to Steve Adamczyk
comment in DR #291 (and http://tinyurl.com/2kdtk). According to that comment
the copy constructor requirement was explicitly removed to allow template
converting constructors which is *not* copy-constructor. This relaxation
also (accidentally?) allows other converting constructors since they are as
good as template converting constructor in context of copy initialization
from the same type.

This means that X const& r = X() might produce the following code:
1) Construct additional const temporary using X::X(ref) which requires call
to the conversion operator. This is allowed since the initialization is from
the same type.
2) Repeat X >= 0 times: construct additional const temporary from the const
r-value.
3) Bind the final r-value to the reference

The fact that the additional temporary is const might, theoretically,
encourage the optimizer to generate faster code but AFAIK no C++ optimizer
is actually aware about the existence of C++ const and *ignore* it. Anyway,
we don't really care about this elided coping constraint since if compiler
actually makes additional coping then it probably has very good reason:
X const& r = true ? X() : X(); // VC and GCC introduce additional r-value
using the "r-value" move constructor.

>> and AFAICT it was discussed during the MoJo days.
>
> Yep. I knew about it then, but it's so easy forgotten when you're
> hunting for the elusive "move"

I think that MoJo also achived the "move" goal but your solution is more
elegant.

>> IMHO the current standard explicitly allows it (per 8.5.3/5/2/1) and
>> EDG is not very consistent about it:
>>
>> auto_ptr<Base> const& r = auto_ptr<Derived>(); // accepted by EDG
>> auto_ptr<Base> const& r = auto_ptr<Base>(); // rejected by EDG
>
> I believe that those two cases use different rules. In the first case
> you have an implicit conversion, while in the second case you only
> have copy initialization.

I just presented this case to show that even EDG has problems with
initialization.
The first case is obviously forbidden by TC1 #84, which most of the times
EDG and all compilers respects.
The second case is our case and it is, IMO, explicitly allowed.

Rani


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk