Boost logo

Boost Users :

Subject: Re: [Boost-users] [lambda] How to write a lambda functor that returns a new functor
From: Thomas Heller (thom.heller_at_[hidden])
Date: 2011-03-10 07:25:37


On Thu, Mar 10, 2011 at 12:50 PM, Thomas Heller
<thom.heller_at_[hidden]> wrote:
> On Thu, Mar 10, 2011 at 11:12 AM, Sebastian Theophil
> <stheophil_at_[hidden]> wrote:
>> Steven,
>>
>>>
>>> On 03/09/2011 06:11 AM, Sebastian Theophil wrote:
>>> > How can I write a lambda expression with two placeholders, one for
>> the
>>> > callable object, and one for the function argument, such that
>>> > supplying the callable object first returns a unary function?
>>>
>>> In this case, boost::lambda::_1 by itself does what you want, because
>> the
>>> callable object itself is a unary function.
>>
>> That is true of course, I was trying to solve a slightly more
>> complicated problem though. I have solved the problem finally, although
>> I hoped there was a more elegant solution:
>>
>> struct FCreateBind {
>>        typedef boost::_bi::bind_t<bool, Callable,
>> boost::_bi::list2<boost::arg<1>, boost::arg<2> >  > result_type;
>>        result_type operator()( Callable const& c ) const {
>>            return boost::bind<bool>(c, _1);
>>        }
>> };
>> BOOST_AUTO(generate, boost::bind(FCreateBind(), _1));
>>
>> BOOST_AUTO(fn, generate(Callable());
>> bool b = fn(Arg());
>>
>> Of course, in this simple example I could just write
>> BOOST_AUTO(generate, boost::lambda::_1) since Callable itself is the
>> callable object. But I was looking for a way to set the arguments of
>> Callable beforehand so the generated function fn is a nullary function.
>> This solution would let me do this inside FCreateBind.
>>
>> FCreateBind can probably be eliminated as well, but I have not yet
>> figured out how to define the pointer to the overloaded global function
>> boost::bind.
>>
>> Regards
>> Sebastian
>
> Hi,
>
> Sorry for the late reply, what you were trying to achieve is possible
> with phoenix V3 (doesn't seem to work with V2). Here is the code:

It turns out it does work with V2 ... the trick is to not use
temporaries with phoenix V2 ... and
callable has to be adapted to conform to the phoenix result type
deduction protocol

> using boost::phoenix::lambda;
> using boost::phoenix::bind;
> using boost::phoenix::placeholders::_1;
> using boost::phoenix::local_names::_a;
>
> auto const generate = lambda(_a = _1)[bind(_a, _1)];
> auto const fn            = generate(Callable());
>
> Here is how it works:
> generate is a lambda that binds its first argument (this is done by
> capturing the actual argument to a local). By calling generate with an
> appropriate callable the returned function can be called again which
> effectively leads to the execution of the bind call.
> You currently need to define the functions as "auto const" cause there
> is a bug in the result type deduction (will be fixed soon).
>
> HTH,
> Thomas
>


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net