Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Interface problem

Reply
Thread Tools

Interface problem

 
 
StephQ
Guest
Posts: n/a
 
      06-04-2007
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 ).

Do you have any suggestion?

Thank you!

Cheers
StephQ

 
Reply With Quote
 
 
 
 
witkamp
Guest
Posts: n/a
 
      06-05-2007
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 <(E-Mail Removed)> 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 ).
>
> Do you have any suggestion?
>
> Thank you!
>
> Cheers
> StephQ



 
Reply With Quote
 
 
 
 
StephQ
Guest
Posts: n/a
 
      06-05-2007
> 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

 
Reply With Quote
 
StephQ
Guest
Posts: n/a
 
      06-05-2007
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






 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Going from higher security level interface to lower security interface- HELP!!! - AM Cisco 4 12-28-2004 09:52 PM
PCI interface or USB interface David Wireless Networking 4 09-16-2004 01:01 PM
allow ssh only on outside interface, but telnet on inside interface of router no-one Cisco 0 07-28-2004 04:17 PM
PIX: how to allow 1 host from outside interface to access another host on the inside interface? jonnah Cisco 1 04-21-2004 02:26 PM
static nat between phisical interface and virtual interface on same ethernet Andrea Cisco 0 04-19-2004 09:37 AM



Advertisments