By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,413 Members | 996 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,413 IT Pros & Developers. It's quick & easy.

Interface problem

P: n/a
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

Jun 4 '07 #1
Share this Question
Share on Google+
3 Replies


P: n/a
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<Tmake_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<TdriftAnalysis(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.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::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

Jun 5 '07 #2

P: n/a
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<Tmake_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<TdriftAnalysis(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

Jun 5 '07 #3

P: n/a
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


Jun 5 '07 #4

This discussion thread is closed

Replies have been disabled for this discussion.