From: Eric Niebler (eric_at_[hidden])
Date: 2008-04-05 21:26:17
Peter Dimov wrote:
> Eric Niebler:
>> make_plus is trickier. It must be optimal and safe. When passed lvalues,
>> it should return a new node that holds the children by reference. When
>> passed rvalues, it should return a new node that hold the children by
>> == Problem ==
>> Here's the thing ... I have no idea how to implement make_plus as a TR1
>> function object.
> I think that you are right; you can't implement make_plus as a C++03
> function object. result_of is a red herring. The missing part is &&, not
> decltype (which result_of is supposed to approximate).
> You can do this:
>> struct make_plus
>> template<typename Sig> struct impl;
>> template<typename This, typename Left, typename Right>
>> struct impl< This(Left, Right) >
>> // Left and Right are allowed to be reference types
>> typedef plus<Left, Right>::type result_type;
>> result_type operator()(
>> typename add_const_ref<Left>::type left
>> ,typename add_const_ref<Right>::type right
>> ) const
>> return result_type(left, right);
> but it's not a function object.
Correct. However, I can do this:
struct make_plus : function_adaptor<make_plus>
// same as before
where function_adaptor implements the TR1 function object protocol and
makes some guess about const-ref arguments -- probably that they are
rvalues. It could even implement the reference_wrapper gunk to treat
reference_wrapper<X> arguments as if they were X&.
This is the route Proto is taking. Proto can query a function object F
if it uses this protocol and use it if it's available, getting correct
lvalue/rvalue handling. If it's not available, it uses result_of,
stripping references from argument types first.
I think I got the idea from reading through Egg's documentation. It
seems like if this sort of thing doesn't exist there, it probably
-- Eric Niebler Boost Consulting www.boost-consulting.com