Interface problem

Discussion in 'C++' started by StephQ, Jun 4, 2007.

  1. StephQ

    StephQ Guest

    I'm writing some algorithms that works on generic functions using
    boost::bind.
    My problem is that class templates can never be deduced.

    In the simplest cases I just write the class like:

    class Legendre
    {
    ....
    public:
    template<class F>
    static double computeIntegral( const F& f );
    }

    double value = Legendre::computeIntegral(boost::bind( &Sde::drift,
    &sde, _1 ));

    However in more complext examples, I have to work with classes with
    non static memeber fucntions.
    For example becouse I need to store data previously calculated about
    the function for efficecny reasons.
    I would like to "fix" the F at the moment of the construction of the
    class and then invoke member functions of the class to perform
    operations.

    That is I would like to being able to do something like:

    template<class F>
    class FunctionAnalysis
    {
    private:

    F& function;

    public:
    FunctionAnalysis( const F& f );

    double operation1();
    double operation2();
    }

    template<class F>
    FunctionAnalysis<F>::FunctionAnalysis( const F& f)
    :
    function(f)
    {}

    FunctionAnalysis driftAnalysis(boost::bind( &Sde::drift, &sde, _1 ));
    double x = driftAnalysis.operation1();
    double y = driftAnalysis.operation2();

    There are two problems:
    1) I class template arguments can never be deduced
    2) driftAnalysis is not of type FunctionAnalysis

    I can solve the fist problem using the same approach of make_pair, but
    I dont't see any way to solve th second problem.

    The objective is to avoid having to specify the template parameter of
    the class (and using boos::bind you can easily see why :D ).

    Do you have any suggestion?

    Thank you!

    Cheers
    StephQ
    StephQ, Jun 4, 2007
    #1
    1. Advertising

  2. StephQ

    witkamp Guest

    Problem 1.
    Only template functions can deduce types from an argument list. This
    excludes C++ constructors!
    The common solution for this is a make_function() template function.
    Example:

    template<typename T>
    FunctionAnalysis<T> make_analysis(const T& func)
    {
    return FunctionAnalysis<T>(func);
    }

    Problem 2.
    You are using a template with out template parameters. It needs to be
    some thing more like this

    typedef boost::bind( &Sde::drift, &sde, _1 )::type;
    FunctionAnalysis<T> driftAnalysis(boost::bind( &Sde::drift, &sde,
    _1 ));

    But this is no fun.


    You should really not pass boost::bind types into template parameters
    like this. Here is what I would propose.

    Alternate Solution

    class FunctionAnalysis
    {
    private:
    boost::function<double(double)> function;

    public:
    FunctionAnalysis(boost::function<double(double)> f );
    double operation1();
    double operation2();
    }

    // use it like this without any trouble

    FunctionAnalysis driftAnalysis(boost::bind( &Sde::drift, &sde, _1 ));
    double x = driftAnalysis.operation1();
    double y = driftAnalysis.operation2();



    On Jun 4, 11:10 am, StephQ <> wrote:
    > I'm writing some algorithms that works on generic functions using
    > boost::bind.
    > My problem is that class templates can never be deduced.
    >
    > In the simplest cases I just write the class like:
    >
    > class Legendre
    > {
    > ...
    > public:
    > template<class F>
    > static double computeIntegral( const F& f );
    >
    > }
    >
    > double value = Legendre::computeIntegral(boost::bind( &Sde::drift,
    > &sde, _1 ));
    >
    > However in more complext examples, I have to work with classes with
    > non static memeber fucntions.
    > For example becouse I need to store data previously calculated about
    > the function for efficecny reasons.
    > I would like to "fix" the F at the moment of the construction of the
    > class and then invoke member functions of the class to perform
    > operations.
    >
    > That is I would like to being able to do something like:
    >
    > template<class F>
    > class FunctionAnalysis
    > {
    > private:
    >
    > F& function;
    >
    > public:
    > FunctionAnalysis( const F& f );
    >
    > double operation1();
    > double operation2();
    >
    > }
    >
    > template<class F>
    > FunctionAnalysis<F>::FunctionAnalysis( const F& f)
    > :
    > function(f)
    > {}
    >
    > FunctionAnalysis driftAnalysis(boost::bind( &Sde::drift, &sde, _1 ));
    > double x = driftAnalysis.operation1();
    > double y = driftAnalysis.operation2();
    >
    > There are two problems:
    > 1) I class template arguments can never be deduced
    > 2) driftAnalysis is not of type FunctionAnalysis
    >
    > I can solve the fist problem using the same approach of make_pair, but
    > I dont't see any way to solve th second problem.
    >
    > The objective is to avoid having to specify the template parameter of
    > the class (and using boos::bind you can easily see why :D ).
    >
    > Do you have any suggestion?
    >
    > Thank you!
    >
    > Cheers
    > StephQ
    witkamp, Jun 5, 2007
    #2
    1. Advertising

  3. StephQ

    StephQ Guest

    > Only template functions can deduce types from an argument list. This
    > excludes C++ constructors!
    > The common solution for this is a make_function() template function.
    > Example:
    >
    > template<typename T>
    > FunctionAnalysis<T> make_analysis(const T& func)
    > {
    > return FunctionAnalysis<T>(func);
    >
    > }


    Eaxctly what I was saying abaout make_pair.

    > Problem 2.
    > You are using a template with out template parameters. It needs to be
    > some thing more like this
    >
    > typedef boost::bind( &Sde::drift, &sde, _1 )::type;
    > FunctionAnalysis<T> driftAnalysis(boost::bind( &Sde::drift, &sde,
    > _1 ));
    >
    > But this is no fun.


    I agree :)

    > You should really not pass boost::bind types into template parameters
    > like this. Here is what I would propose.
    >
    > Alternate Solution
    >
    > class FunctionAnalysis
    > {
    > private:
    > boost::function<double(double)> function;
    >
    > public:
    > FunctionAnalysis(boost::function<double(double)> f );
    > double operation1();
    > double operation2();
    >
    > }
    >
    > // use it like this without any trouble
    >
    > FunctionAnalysis driftAnalysis(boost::bind( &Sde::drift, &sde, _1 ));
    > double x = driftAnalysis.operation1();
    > double y = driftAnalysis.operation2();


    Thank you very much, it's excactly what I was searching for.
    I just ignored the existance of boost::function.

    Cheers
    StephQ
    StephQ, Jun 5, 2007
    #3
  4. StephQ

    StephQ Guest

    I just run in the following problem.
    I'm using the gsl library that requires an input function to be of the
    form:

    struct gslFunction
    {
    double (*func)(double x, void* p) function;
    void* params;
    }


    To be able to interface to the gsl I wrote this "converter" (based on
    root's mathmore library gsl wrapper):


    // Use in combination with boost::bind.
    template<class F>
    static double gslFunctionAdapter( double x, void* p)
    {
    // Here I do recover the "right" pointer, safer to use static_cast
    than reinterpret_cast.
    F* function = static_cast<F*>( p );
    return (*function)( x );
    }

    template<class F>
    gsl_function convertToGslFunction( const F& f )
    {
    gsl_function gslFunction;

    const void* p = &f;
    assert (p != 0);

    gslFunction.function = &gslFunctionAdapter<F>;
    gslFunction.params = const_cast<void*>( p ); // Just to eliminate
    the const.

    return gslFunction;
    }

    and use this like:
    gslFunction gslF = convertToGslFunction( boost::bind( &Sde::drift,
    &sde, _1 ) );

    However the problem is that now I'm using boost::function in my
    algorithms, following your suggestion.
    So in an algorithm I get into the situation:

    boost::function<double (double)> f = boost::bind( &Sde::drift, &sde,
    _1 );
    gslFunction gslF = convertToGslFunction( f );

    I know that this "double-wrapper" is bad for efficency, but I can't
    see any other way to use the gsl library without modification on the
    gsl library itself.
    The problem is that this does not work! When I call the gslF the
    software crash.
    Debugger inspection reveals that the line:

    F* function = static_cast<F*>( p ); // in gslFunctionAdapeter

    fails to "recover" my boost::funcion.

    Is there anything I could do to solve the situation?

    The two requirements are:

    1) Be able to implement the approach suggested in the post above: that
    is have boost::function private member data in my algorithms

    2) Interface to the gslFunction struct without any modification to the
    gsl library.

    Thank you again for your help.

    Best Regards
    StephQ
    StephQ, Jun 5, 2007
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Wildepiet
    Replies:
    0
    Views:
    1,848
    Wildepiet
    Jun 14, 2004
  2. cyberco
    Replies:
    8
    Views:
    478
    cyberco
    Feb 25, 2006
  3. Xah Lee
    Replies:
    15
    Views:
    572
    Sherm Pendley
    Mar 23, 2007
  4. Xah Lee
    Replies:
    15
    Views:
    617
    Sherm Pendley
    Mar 23, 2007
  5. Replies:
    4
    Views:
    335
    timjowers
    Nov 2, 2007
Loading...

Share This Page