Interface problem

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • StephQ

    Interface problem

    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::compu teIntegral(boos t::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 FunctionAnalysi s
    {
    private:

    F& function;

    public:
    FunctionAnalysi s( const F& f );

    double operation1();
    double operation2();
    }

    template<class F>
    FunctionAnalysi s<F>::FunctionA nalysis( const F& f)
    :
    function(f)
    {}

    FunctionAnalysi s driftAnalysis(b oost::bind( &Sde::drift, &sde, _1 ));
    double x = driftAnalysis.o peration1();
    double y = driftAnalysis.o peration2();

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

    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

    #2
    Re: Interface problem

    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<typena me T>
    FunctionAnalysi s<Tmake_analysi s(const T& func)
    {
    return FunctionAnalysi s<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;
    FunctionAnalysi s<TdriftAnalysi s(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 FunctionAnalysi s
    {
    private:
    boost::function <double(double) function;

    public:
    FunctionAnalysi s(boost::functi on<double(doubl e)f );
    double operation1();
    double operation2();
    }

    // use it like this without any trouble

    FunctionAnalysi s driftAnalysis(b oost::bind( &Sde::drift, &sde, _1 ));
    double x = driftAnalysis.o peration1();
    double y = driftAnalysis.o peration2();



    On Jun 4, 11:10 am, StephQ <askmeo...@mail inator.comwrote :
    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::compu teIntegral(boos t::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 FunctionAnalysi s
    {
    private:
    >
    F& function;
    >
    public:
    FunctionAnalysi s( const F& f );
    >
    double operation1();
    double operation2();
    >
    }
    >
    template<class F>
    FunctionAnalysi s<F>::FunctionA nalysis( const F& f)
    :
    function(f)
    {}
    >
    FunctionAnalysi s driftAnalysis(b oost::bind( &Sde::drift, &sde, _1 ));
    double x = driftAnalysis.o peration1();
    double y = driftAnalysis.o peration2();
    >
    There are two problems:
    1) I class template arguments can never be deduced
    2) driftAnalysis is not of type FunctionAnalysi s
    >
    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

    Comment

    • StephQ

      #3
      Re: Interface problem

      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<typena me T>
      FunctionAnalysi s<Tmake_analysi s(const T& func)
      {
      return FunctionAnalysi s<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;
      FunctionAnalysi s<TdriftAnalysi s(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 FunctionAnalysi s
      {
      private:
      boost::function <double(double) function;
      >
      public:
      FunctionAnalysi s(boost::functi on<double(doubl e)f );
      double operation1();
      double operation2();
      >
      }
      >
      // use it like this without any trouble
      >
      FunctionAnalysi s driftAnalysis(b oost::bind( &Sde::drift, &sde, _1 ));
      double x = driftAnalysis.o peration1();
      double y = driftAnalysis.o peration2();
      Thank you very much, it's excactly what I was searching for.
      I just ignored the existance of boost::function .

      Cheers
      StephQ

      Comment

      • StephQ

        #4
        Re: Interface problem

        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 gslFunctionAdap ter( double x, void* p)
        {
        // Here I do recover the "right" pointer, safer to use static_cast
        than reinterpret_cas t.
        F* function = static_cast<F*> ( p );
        return (*function)( x );
        }

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

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

        gslFunction.fun ction = &gslFunctionAda pter<F>;
        gslFunction.par ams = const_cast<void *>( p ); // Just to eliminate
        the const.

        return gslFunction;
        }

        and use this like:
        gslFunction gslF = convertToGslFun ction( 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 = convertToGslFun ction( 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 gslFunctionAdap eter

        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






        Comment

        Working...