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.


>>>>> 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,


> 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

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