Boost logo

Boost :

From: Eric Niebler (eric_at_[hidden])
Date: 2008-07-01 14:04:19

Giovanni Piero Deretta wrote:
> On Tue, Jul 1, 2008 at 6:57 PM, Eric Niebler <eric_at_[hidden]> wrote:
>> David Abrahams wrote:
>>> Eric Niebler wrote:
>>>> David Abrahams wrote:
>>>>> I don't suppose it's possible to forward lvalues and
>>>>> const rvalues as lvalues, and mutable rvalues as rvalues? I haven't
>>>>> thought of a way, but that would be as close to "perfect" as we might
>>>>> expect to get in C++0x and it would be close enough for me :-)
>>>> We would need 2^N overloads,
>>> That's OK for small N
>> boost::function and phoenix have argument limits of 10 by default. 2^10 is a
>> big number. Can't wait for variadics and rvalue refs.
> I use a wrapper that does perfect forwarding up to 5 arguments (and
> all ref/all const ref for the remaining 10). I never needed more than
> that and I do not think it has an important contribution to compile
> time (that is, heavy lambda usage will kill compile time way more than
> that).

My Phoenix/Proto port lets you do something similar. The first N
arguments are handled "perfectly", and the rest are taken by const-ref
(where N is configurable). I had to turn it off (N=0 by default) because
even at N=3 it was slaughtering compile times. If you have to choose
between 2^N overloads of operator(), you have to calculate the return
types of all the overloads -- even the ones that won't get selected --
and that is hella expensive. I can't see a way around it, except to
somehow normalize the const-ref-ness of each arg before doing the return
type calculation, so that template memoization kicks in, but that would
cause the return type calculation to be wrong.

>>>> and it would be unsound because it would
>>>> incorrectly forward const rvalues as lvalues.
>>> Can you show me an example of a "sound" function that treats a const
>>> rvalue differently from an lvalue, please?
>> fusion::make_vector(), for instance. It returns a fusion::vector<> where the
>> members can be held by value or by reference. Getting it wrong can lead to
>> dangling references. Proto has similar function objects that need to be
>> careful about the lifetime of temporaries.
> IMHO you can ever safely hold on a parameter by reference unless you
> somehow explicitly decorate that parameter (with reference_wrapper for
> example). I do not see how brute force forwarding or C++0x perfect
> forwarding change anything. I should probably read again the thread
> referenced by David Abrahams

IIRC, that was ultimately the conclusion reached in that thread.

Eric Niebler
BoostPro Computing

Boost list run by bdawes at, gregod at, cpdaniel at, john at