Home     |     .Net Programming    |     cSharp Home    |     Sql Server Home    |     Javascript / Client Side Development     |     Ajax Programming

Ruby on Rails Development     |     Perl Programming     |     C Programming Language     |     C++ Programming     |     IT Jobs

Python Programming Language     |     Laptop Suggestions?    |     TCL Scripting     |     Fortran Programming     |     Scheme Programming Language


 
 
Cervo Technologies
The Right Source to Outsource

MS Dynamics CRM 3.0

C++ Programming

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::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

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 <askmeo@mailinator.com> wrote:

> 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 :)

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

Cheers
StephQ

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

Add to del.icio.us | Digg this | Stumble it | Powered by Megasolutions Inc