Boost logo

Boost :

From: Eric Niebler (eric_at_[hidden])
Date: 2008-07-01 15:52:58


David Abrahams wrote:
> Eric Niebler wrote:
>> David Abrahams wrote:
>>> Eric Niebler wrote:
>>>
>>> -- snip 2^10 overloads --
>>>
>>> Yeah, that's probably too much, but I'm not sure we have to support
>>> forwarding for that many arguments. The only thing rvalue forwarding
>>> buys you (and it can be a big win) is the ability for the wrapped thing
>>> to make certain optimizations. It's a good idea when you can do it. If
>>> you can't do it, you can fall back to lvalues and in C++03 you've still
>>> done a credible job.
>> Even 2^3 overloads has a *very* noticeable effect on compile times.
>
> 8 overloads hurts compile times?

Yes, because for each function invocation you have to calculate the
return type 8x in 8 different ways. That can cause 8x the number of
templates to be instantiated.

>>> After all, any time you build a vector of references from lvalues, those
>>> references (or copies thereof) can be made to dangle.
>>>
>>> That doesn't mean a wrapper function should not forward non-const
>>> rvalues to its wrapee.
>> The wrapper I wrote (poly_function) passes arguments to the wrapped
>> function and also passes along information about whether the user
>> specified that argument as an lvalue (reference-wrapped) or not.
>
> Understood
>
>> That's
>> all. Whether the wrapped function *actually* accepts its (rvalue)
>> arguments as "T" or "T const &" is a different issue. poly_function
>> doesn't care.
>
> Understood again. I don't get what you're driving at, though.
>
>> When you use poly_function, you basically write a template that
>> generates mono-morphic function objects like this:
>>
>> template< class Arg0, class Arg1 >
>> struct my_function
>> {
>> typedef ... result_type;
>>
>> result_type operator()(poly_arg<Arg0> a0, poly_arg<Arg1> a1) const
>> { ... }
>> };
>>
>> If ArgN is a reference, then the user has reference-wrapped the
>> argument. If it isn't a reference, it was passed unwrapped.
>
> Pretty much what I expected. Hm, what is poly_arg<T> ?

It's not actually needed, but it's handy. Think of it as a replacement
for typename add_reference<typename add_const<ArgN>::type>::type.

>> What poly_function buys you is:
>>
>> 1) It implements the result_of protocol for you, correctly handling
>> const, refs, and reference wrappers.
>>
>> 2) It unwraps any reference wrapped args before forwarding them.
>>
>> 3) It makes writing a polymorphic function object as simple as writing a
>> monomorphic one.
>
> All good things, although I think I contest point 3. It may be better,
> but it can't be _as simple_ if you need poly_arg, template arguments,
> and a poly_function wrapper.

OK.

>>>>> I just think that since you don't have permission to mutate a const
>>>>> rvalue anyway, forwarding it as a const reference doesn't really hurt
>>>>> anyone.
>>>> When I've gotten it wrong, it hurts.
>>> Maybe you're making assumptions that you really can't afford to make
>>> (that storing a reference to an lvalue, even when properly detected, is
>>> a good idea).
>> Please, I'm not trying to detect lvalue/rvalue-ness!
>
> I'm sorry if it sounded like you were being attacked; I was just trying
> to find an explanation for the hurt you described in the context of my
> understanding of the meaning of "const rvalue." Maybe where one really
> gets hurt is in dealing with return values: if you treat const rvalues
> as const lvalues you *will* dangle,

Yes.

> and if you treat const lvalues as
> const rvalues you will cause the wrong semantics in way too many common
> cases.

Yes. I was trying to illustrate those points with the
fusion::make_vector() example.

>> I'm letting users opt-in with reference_wrapper.
>
> I understand that's the scope you chose. I was only trying to explore
> whether that facility can usefully be pushed a little further so that we
> don't lose move semantics inside of forwarded arguments. Well, I guess
> we don't, if we assume everything's an rvalue by default :-)

I'm not sure if changes are needed to better support move semantics, or
what they would be. Feedback is welcome.

-- 
Eric Niebler
BoostPro Computing
http://www.boostpro.com

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