
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?
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> ?
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.
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 :-) -- Dave Abrahams BoostPro Computing http://www.boostpro.com