$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
Subject: Re: [boost] [interprocess] Compile problem with 1.39 and trunk
From: Thomas Klimpel (Thomas.Klimpel_at_[hidden])
Date: 2009-08-26 06:37:50
Mathias Gaunard wrote:
> Ion Gaztañaga wrote:
> > That was a change in the forwarding code. Since perfect forwarding can't
> > be achieved in C++03
>
> Really?
> Can't you just overload all the possible const/non-const combinations?
> That would surely do forwarding of constness just fine.
> Of course, this is only feasible if you have few arguments.
Until recently, I thought that the "perfect forwarding" problem was a technical defect of C++03, but then I read through the following:
Robert Jones wrote:
> There's a terrific article about RVO and copy elision by Dave A at
>
> http://cpp-next.com/
somewhere down, we have the following
Dave Abrahams wrote:
> One place you can apply this guideline immediately is in assignment operators.
> The canonical, easy-to-write, always-correct, strong-guarantee, copy-and-swap
> assignment operator is often seen written this way:
>
> T& T::operator=(T const& x) // x is a reference to the source
> {
> T tmp(x); // copy construction of tmp does the hard work
> swap(*this, tmp); // trade our resources for tmp's
> return *this; // our (old) resources get destroyed with tmp
> }
>
> but in light of copy elision, that formulation is glaringly inefficient! It's now "obvious" that the correct way to write a copy-and-swap assignment is:
>
> T& operator=(T x) // x is a copy of the source; hard work already done
> {
> swap(*this, x); // trade our resources for x's
> return *this; // our (old) resources get destroyed with x
> }
>
> Reality Bites
So operator= takes "T x" as an argument, but if the function that want to forward its arguments also takes "T x" as argument and passes "x" as argument to operator=, neither RVO nor "copy elision" can help. So something called "rvalues" could be introduced in an attempt to help, let's write it as "T&& x". But at which point in time should the destructor of x now be called? The implementation of operator= probably wants to rely on the fact that the destructor of x gets called upon exit from operator=. But if the destructor of x should also be called upon exist of the function that forwarded x, we must create at least one additional x object so that we have room for two destructor calls. The other alternative is that operator= takes its argument as "T&& x", but now it can no longer rely on the fact that the destructor of x gets called upon exit from operator=. So operator= must now worry about the resources owned by x upon exit, and possibly try to free them. So it is unclear to me whether the "perfect forwarding" problem is solvable at all.
Regards,
Thomas