$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Howard Hinnant (hinnant_at_[hidden])
Date: 2002-03-10 13:50:36
On Sunday, March 10, 2002, at 12:36  PM, brangdon_at_[hidden] 
wrote:
>> relocate construct is not implementable for those classes that have a
>> base class or member classes that do not support move construct (in
>> order to preserve proper order of construction/destruction of base and
>> member objects).
>
> OK, this is new to me.
>
> How does move help with the order of construction/destruction here? What
> is "proper order", anyway? At first sight, either construction order or
> reverse construction order are equally applicable. Either can be wrong.
As you know, in present day C++ base (and virtual base) classes are 
constructed first, then members are constructed in the order that they 
appear in the declaration.  Destruction occurs in the reverse order.
Although it might be possible to make an exception on the order of 
destruction of members during a relocate construct, I don't even see 
that possibility for base classes.  Consider:
struct Base {};
struct Derived
        : Base
{};
Also consider the possibility that Base is designed to be derived from 
by client code.  Thus the author of Derived probably has to respect some 
encapsulation of Base.  For Derived to relocate construct it must first 
ask Base to relocate construct.  After this happens Derived can now 
relocate construct its members.  And finally the entire object is 
destructed.
Note that the base class got destructed first.  During the period that 
Derived was busy relocating its members, it was operating with a 
destructed Base.  This is a rather bizarre configuration.  What happens 
if Derived needs to ask Base a question?  During an ordinary ~Derived() 
there is an arbitrarily rich communication between Derived and Base 
because Base hasn't been destructed yet.
In a nutshell, I find changing the order of destruction of base classes 
too scary.  Therefore I believe that Derived will have to ask Base to 
move construct itself, leaving behind a valid Base that Derived can 
communicate with during its own destruction, after which ~Base() would 
run.
And the more I thought about this, it occurred to me that changing the 
order of destruction of member objects (from that done in the ordinary 
destructor) is pretty  scary too.
>> 1.  There must be a way to overload a function in such a way as to
>> distinguish between a non-const lvalue, a const lvalue and a non-const
>> rvalue as parameters.
>
> Is this another approach to working with temporaries? I had thought the
> issue would be addressed more directly by turning temporaries into 
> lvalues
> and allowing them to bind to non-const references (with implicit
> conversions disallowed).
Yes this is another approach.  The idea is have a new kind of reference 
that allows temporaries to bind to them, even prefers temporaries in the 
presence of overloading.  It is all still extremely preliminary.  It 
could help in cases like operator+() for a string class (syntax pulled 
out of thin air):
string operator+(const string& x, const string& y) {return string(x) += 
y;}
string operator+(temporary string x, const string& y)     {return x += 
y;}
string operator+(const string& x, temporary string y)     {return y += 
x;}
string operator+(temporary string x, temporary string y)  {return x += 
y;}
...
string s = s1 + s2 + s3 + s4;
The versions taking a temporary know that they can pilfer that argument 
with impunity.  There is no need to copy construct one of the 
arguments.  You can just add to the temporary and return it.  With 
sufficient rvo (possibly aided by move semantics), unnecessary 
temporaries could be a thing of the past.
>  This (and typeof) are the two most important
> language changes I hope for.
Agreed that both of these are very important.  I personally consider the 
introduction of a C99 compatible long long as the only language change 
more important than these two (but not nearly so difficult nor 
controversial ... I hope!).
-Howard