Boost logo

Boost Users :

Subject: Re: [Boost-users] [lamda] smart self binding of a function object
From: alfC (alfredo.correa_at_[hidden])
Date: 2010-05-27 03:25:08


On May 11, 7:10 am, Steven Watanabe <watanab..._at_[hidden]> wrote:
> > since I have access to f I would like to make fsmartenough to handle
> > its own binding. Eg.
> You'll have to make operator() a template:
> template<class T>
> function<double(double)> operator()(const T& x_arg, double y_arg);

Thank you Steven for pointing that out.

This is simplest still useful solution I found. I realized that
returning function<double(double)> would defeat the purpose since it
is not a lambda expression an I would need bind again to insert it in
a lambda expression

this is the soltution
class A{
                typedef A this_type;
                double operator()(double const& x) const{return evaluate(x);} //this
is the function that performs the actual work
                //the following creates a lambda expression using
operator()
                template<class LambdaExp>
                lambda_functor<lambda_functor_base<
                        action<3,
                                function_action<3>
>,
                        tuple<
                                double (this_type::* const)(const double&)const,
                                const this_type, //this class
                                lambda_functor<LambdaExp> const
>
> > operator()(lambda_functor<LambdaExp> const& exp) const{
                        return bind(
                                static_cast<double(this_type::*)(double const&)
const>(&this_type::operator()),
                                static_cast<this_type const&>(*this), //static_cast not necesary
but maybe usefull if CRTP worked
                                exp
                        );
                }
}
it can be used as

A a;
a(5.); //evaluates at 5.
a( _1 + _1) or any lambda expression); //gives a bind lambda
expression.

as you see the most complicated part is the return type of the
function.
It can be generalized to functions that take two arguments, if mixed
symbolic/numeric evaluation is needed other combinations of can be
made or simply using lambda::constant for one or two of the arguments.

I tried to use CRTP (e.g. class A: public self_binder<A>{...}) to
define the new member in a more generic way but I couldn't because the
template member function in a base (parent) class can not be resolved
by calling A::operator()(lambda_expr).

Maybe as OvermindDL1 said Boost.Phoenix can do better in terms of
shorted syntax or by allowing CRTP in some way. Unfortunately I don't
know enough Phoenix, maybe Phoenix has a "function" class that is a
phoenix-lambda by itself.

Thank you,
Alfredo


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