Boost logo

Boost :

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
>> value.
>> == 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
should. Shunsuke?

Eric Niebler
Boost Consulting

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