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

passing member function pointers to a function

P: n/a
I am a c++ newbie, so please excuse the ignorance of this question.

I am interested in a way of having a class call a general member
function of another class.

Specifically, I am trying to write an ordinary differential equation
class that would solve a general equation in the form:
dx/dt = f(x,t).

The ode class shouldn't know anything about f, except how to call it.

My first thought was to have a data member that stores a pointer to
the function f like:
double (*f) (double, double);

However, I learned that f could not point to a non-static member
function of a different class. This is bad for me, because I need to
use the solver for functions that are complicated to evaluate and
depend on many parameters. A simple example:

class my_f{ public:
double a;
double f(double x, double t){ return t+x*a;}
};

my_f foo; foo.a = 7;

I would like the ode solver to call foo.f(x,t). I could make

double (my_f::* f)(double, double);

a member of the ode solver, but then I would have to write a new ode
solver for every new class of functions to be used for f or to have
all these derive from some kind of base class, which I would prefer to
avoid.

My question is: is there a simple and elegant way to do this? I would
think that similar issues have been encountered many times before.
Thanks.

Feb 23 '07 #1
Share this Question
Share on Google+
18 Replies


P: n/a
tb*******@gmail.com wrote:
>
My question is: is there a simple and elegant way to do this? I would
think that similar issues have been encountered many times before.
Thanks.
This can help give you an idea how to approach this problem.

-----------------------------------------------

// Use boost/function and functors
#include <boost/function.hpp>

// create a functor
class my_f
{
public:
my_f( double a ) : m_a(a) {}
double operator()(double x, double t){ return t+x*m_a;}
private:
double m_a;
};

// this is another functor
class my_y
{
public:
my_y( double a ) : m_a(a) {}
double operator()(double x, double t) { return t+x*m_a;}
private:
double m_a;
};

class ODE
{
public:
void solve( boost::function<double (double, double)f)
{
// call f here
double result = f( 1.0, 1.0 );
}
};

int
main()
{
ODE solver;
solver.solve( my_f(20.0) );
solver.solve( my_y(100.0) );
}
Feb 23 '07 #2

P: n/a
Please note that my C++ is so rusty it squeaks when I walk.

On Feb 23, 10:36 pm, tbring...@gmail.com wrote:
I am interested in a way of having a class call a general
member function of another class.

Specifically, I am trying to write an ordinary
differential equation class that would solve a general
equation in the form: dx/dt = f(x,t).
I believe you're making a conceptual mistake here. In the
design you're describing f(x,t) is not represented by a
method of a class, but by the class itself, and f a (x,t) -
by an instance of the class representing f(x,t) functions.
That's why you probably shouldn't try passing a pointer to
a method, pass a reference to the object instead. If you
have more general questions about all of this, you probably
should follow-up to comp.object.
The ode class shouldn't know anything about f, except how
to call it.
That's pretty much a textbook description of an interface.

[...]
a member of the ode solver, but then I would have to
write a new ode solver for every new class of functions
to be used for f or to have all these derive from some
kind of base class, which I would prefer to avoid.
That kinda defeats the purpose of OOD, doesn't it?
My question is: is there a simple and elegant way to do
this? I would think that similar issues have been
encountered many times before.
I'm not sure if this will work for you, but consider this
bare-bones implementation:

#include <iostream>

class interface_function
{
public :
virtual double operator ( )
( double x , double t ) const = 0 ;
} ;

class ode
{
public :
static void solve ( const interface_function & f ) ;
} ;

void ode :: solve ( const interface_function & f )
{
std :: cout <<
f
(
static_cast < double ( 1 ) ,
static_cast < double ( 1 )
) ;
std :: cout << std :: endl ;
}

class f : public interface_function
{
public :
double a_ ;
f ( ) : a_ ( 1 ) { }
virtual double operator ( )
( double x , double t ) const ;
} ;

double f :: operator ( )
( double x , double t ) const
{
return t + x * a_ ;
}

class g : public interface_function
{
public :
double a_ ;
g ( ) : a_ ( 1 ) { }
virtual double operator ( )
( double x , double t ) const ;
} ;

double g :: operator ( )
( double x , double t ) const
{
return t - x * a_ ;
}

int main ( )
{
f f1 ;
g g1 ;
ode :: solve ( f1 ) ;
ode :: solve ( g1 ) ;
f1 . a_ = 5 ;
g1 . a_ = 5 ;
ode :: solve ( f1 ) ;
ode :: solve ( g1 ) ;
}

--
roy axenov

Feb 23 '07 #3

P: n/a
tb*******@gmail.com wrote:
I am a c++ newbie, so please excuse the ignorance of this question.

I am interested in a way of having a class call a general member
function of another class.

Specifically, I am trying to write an ordinary differential equation
class that would solve a general equation in the form:
dx/dt = f(x,t).

The ode class shouldn't know anything about f, except how to call it.

My first thought was to have a data member that stores a pointer to
the function f like:
double (*f) (double, double);

However, I learned that f could not point to a non-static member
function of a different class. This is bad for me, because I need to
use the solver for functions that are complicated to evaluate and
depend on many parameters. A simple example:

class my_f{ public:
double a;
double f(double x, double t){ return t+x*a;}
};

my_f foo; foo.a = 7;

I would like the ode solver to call foo.f(x,t). I could make

double (my_f::* f)(double, double);

a member of the ode solver, but then I would have to write a new ode
solver for every new class of functions to be used for f or to have
all these derive from some kind of base class, which I would prefer to
avoid.

My question is: is there a simple and elegant way to do this? I would
think that similar issues have been encountered many times before.
Thanks.
How are you passing the function object to the solver in the first
place? Or perhaps this is really the root of your question? The two
most direct approaches would be to use either inheritance or templates.
In the former, you would have some abstract base class like:

class TwoArgFcn
{
public:
virtual double evaluate( double x, double t) = 0;
};

Then a derived class defines evaluate() as appropriate and your solver
takes an object of type TwoArgFcn& or something similar.

If you use templates, then you solver is templated on the type of the
function object:

template <typename FcnClass>
class Solver
{
public:
Solver( FcnClass& input_fcn) : input_fcn( input_fcn) {}

private:
void solve() { /* use input_fcn.f() */ }

FcnClass& input_fcn;
};

Here you assume that the template class FcnClass defines some function f
(which will be verified when the template is instatiated).

-Mark
Feb 23 '07 #4

P: n/a
Thanks for the suggestions everyone. I guess what I had in mind was
something along the lines of:

class ode_solver{
...
double (*f) (double,double);
void solve();
...
};

ode_solver s;
s.f = & arbitraryclass.arbitraryfunction;
s.solve();

This would work perfectly fine if f pointed to a non-member function
-- and this idea is used a lot in C.

I will be needing to use the ode_solver with an extremely general set
of functions f that might come from all different kinds of classes.
It is not an option to guarantee that f is a member of a particular
class or has a particular name (i.e. f or operator(double,double)). I
would much prefer if I didn't have to modify the code of
arbitraryclass, if that's possible.

So, there is no way to do something like this in C++ with member
functions?

I could make "every" class in my library derive from

class its_a_class{
// empty
};

class my_class : public its_a_class{
double f1(double x, double t);
double f2(double x, double t);
....
// lots of data/functions that f1 and f2 need to know about/call
....
};

class ode_solver : public its_a_class{
double (its_a_class:: *f)(double, double);
....
};

my_class foo;
ode_solver s;
....
s.f = & foo.f1;
s.solve;
....
s.f = &foo.f2;
s.solve;

etc.

Would this work? But, it's ridiculous, right? There's not a better
way?

It seems like the suggestions are along the lines of that f should be
itself a class. So...

class ode_solver{
TwoArgFunc f;
};

but then...

class my_class{
TwoArgFunc f1;
....
};

s.f = foo.f1;

is no good, because f1 needs to know about the data of my_class and to
call other functions in my_class to evaluate itself (like a member
function does).

Thanks again.


On Feb 23, 5:04 pm, Mark P <use...@fall2005REMOVE.fastmailCAPS.fm>
wrote:
tbring...@gmail.com wrote:
I am a c++ newbie, so please excuse the ignorance of this question.
I am interested in a way of having a class call a general member
function of another class.
Specifically, I am trying to write an ordinary differential equation
class that would solve a general equation in the form:
dx/dt = f(x,t).
The ode class shouldn't know anything about f, except how to call it.
My first thought was to have a data member that stores a pointer to
the function f like:
double (*f) (double, double);
However, I learned that f could not point to a non-static member
function of a different class. This is bad for me, because I need to
use the solver for functions that are complicated to evaluate and
depend on many parameters. A simple example:
class my_f{ public:
double a;
double f(double x, double t){ return t+x*a;}
};
my_f foo; foo.a = 7;
I would like the ode solver to call foo.f(x,t). I could make
double (my_f::* f)(double, double);
a member of the ode solver, but then I would have to write a new ode
solver for every new class of functions to be used for f or to have
all these derive from some kind of base class, which I would prefer to
avoid.
My question is: is there a simple and elegant way to do this? I would
think that similar issues have been encountered many times before.
Thanks.

How are you passing the function object to the solver in the first
place? Or perhaps this is really the root of your question? The two
most direct approaches would be to use either inheritance or templates.
In the former, you would have some abstract base class like:

class TwoArgFcn
{
public:
virtual double evaluate( double x, double t) = 0;

};

Then a derived class defines evaluate() as appropriate and your solver
takes an object of type TwoArgFcn& or something similar.

If you use templates, then you solver is templated on the type of the
function object:

template <typename FcnClass>
class Solver
{
public:
Solver( FcnClass& input_fcn) : input_fcn( input_fcn) {}

private:
void solve() { /* use input_fcn.f() */ }

FcnClass& input_fcn;

};

Here you assume that the template class FcnClass defines some function f
(which will be verified when the template is instatiated).

-Mark

Feb 23 '07 #5

P: n/a
Thanks for the suggestions everyone. I guess what I had in mind was
something along the lines of:

class ode_solver{
...
double (*f) (double,double);
void solve();
...
};

ode_solver s;
s.f = & arbitraryclass.arbitraryfunction;
s.solve();

This would work perfectly fine if f pointed to a non-member function
-- and this idea is used a lot in C.

I will be needing to use the ode_solver with an extremely general set
of functions f that might come from all different kinds of classes.
It is not an option to guarantee that f is a member of a particular
class or has a particular name (i.e. f or operator(double,double)). I
would much prefer if I didn't have to modify the code of
arbitraryclass, if that's possible.

So, there is no way to do something like this in C++ with member
functions?

I could make "every" class in my library derive from

class its_a_class{
// empty
};

class my_class : public its_a_class{
double f1(double x, double t);
double f2(double x, double t);
....
// lots of data/functions that f1 and f2 need to know about/call
....
};

class ode_solver : public its_a_class{
double (its_a_class:: *f)(double, double);
....
};

my_class foo;
ode_solver s;
....
s.f = & foo.f1;
s.solve;
....
s.f = &foo.f2;
s.solve;

etc.

Would this work? But, it's ridiculous, right? There's not a better
way?

It seems like the suggestions are along the lines of that f should be
itself a class. So...

class ode_solver{
TwoArgFunc f;
};

but then...

class my_class{
TwoArgFunc f1;
....
};

s.f = foo.f1;

is no good, because f1 needs to know about the data of my_class and to
call other functions in my_class to evaluate itself (like a member
function does).

Thanks again.


On Feb 23, 5:04 pm, Mark P <use...@fall2005REMOVE.fastmailCAPS.fm>
wrote:
tbring...@gmail.com wrote:
I am a c++ newbie, so please excuse the ignorance of this question.
I am interested in a way of having a class call a general member
function of another class.
Specifically, I am trying to write an ordinary differential equation
class that would solve a general equation in the form:
dx/dt = f(x,t).
The ode class shouldn't know anything about f, except how to call it.
My first thought was to have a data member that stores a pointer to
the function f like:
double (*f) (double, double);
However, I learned that f could not point to a non-static member
function of a different class. This is bad for me, because I need to
use the solver for functions that are complicated to evaluate and
depend on many parameters. A simple example:
class my_f{ public:
double a;
double f(double x, double t){ return t+x*a;}
};
my_f foo; foo.a = 7;
I would like the ode solver to call foo.f(x,t). I could make
double (my_f::* f)(double, double);
a member of the ode solver, but then I would have to write a new ode
solver for every new class of functions to be used for f or to have
all these derive from some kind of base class, which I would prefer to
avoid.
My question is: is there a simple and elegant way to do this? I would
think that similar issues have been encountered many times before.
Thanks.

How are you passing the function object to the solver in the first
place? Or perhaps this is really the root of your question? The two
most direct approaches would be to use either inheritance or templates.
In the former, you would have some abstract base class like:

class TwoArgFcn
{
public:
virtual double evaluate( double x, double t) = 0;

};

Then a derived class defines evaluate() as appropriate and your solver
takes an object of type TwoArgFcn& or something similar.

If you use templates, then you solver is templated on the type of the
function object:

template <typename FcnClass>
class Solver
{
public:
Solver( FcnClass& input_fcn) : input_fcn( input_fcn) {}

private:
void solve() { /* use input_fcn.f() */ }

FcnClass& input_fcn;

};

Here you assume that the template class FcnClass defines some function f
(which will be verified when the template is instatiated).

-Mark

Feb 23 '07 #6

P: n/a
>
class my_class : public its_a_class{
double f1(double x, double t);
double f2(double x, double t);
...
// lots of data/functions that f1 and f2 need to know about/call
...
};

class ode_solver : public its_a_class{
double (its_a_class:: *f)(double, double);
...
};

my_class foo;
ode_solver s;
...
s.f = & foo.f1;
s.solve;
...
s.f = &foo.f2;
s.solve;

etc.

Would this work? But, it's ridiculous, right? There's not a better
way?
Hi, instead of us trying to determine your program requirements and
write example code that will fit it properly, I think it is better to
just teach you about calling a pointer to a member function because it
is possible to do so.

Here is a guide to doing that:

http://www.parashift.com/c++-faq-lit...o-members.html

Good Luck with that :)
Feb 23 '07 #7

P: n/a

tb*******@gmail.com wrote:
>
My first thought was to have a data member that stores a pointer to
the function f like:
double (*f) (double, double);

but then I would have to write a new ode
solver for every new class of functions to be used for f or to have
all these derive from some kind of base class
Pointer is no needed here, use ordinary member

template<class T>
class
{
T obj;

public:
double f(double x, double t){ return obj.f(x, t);}
};

The main OO design rule is: "find all that can be changed and encapsulate
it". Incapsulator is function or class. You have said, that you will change
implementation of concrete function - see design pattern "strategy".

At design stage to find design patterns without external help do not speak
implementations details (as "pointer") language, do not take the details as
predefined invariants, describe what you want in design terms: interface,
message and implementation, method.

--
Maksim A. Polyanin
http://grizlyk1.narod.ru/cpp_new

"In thi world of fairy tales rolls are liked olso"
/Gnume/
Feb 23 '07 #8

P: n/a

I am aware that it is possible to have a pointer to a member
function. However, such a pointer must know the name of the class
that contains the member function to which it points. This is what I
am trying to circumvent.

Please do not write example code for me if you don't want to. I just
included sample code and details of my project to give make more
concrete what I am trying to do. In the simplest terms, I would just
like to know if there is a way for class A to call a member function
of class B without class A knowing that the function it is calling is
a member of class B.

Thanks.


On Feb 23, 6:32 pm, Piyo <cybermax...@yahoo.comwrote:
class my_class : public its_a_class{
double f1(double x, double t);
double f2(double x, double t);
...
// lots of data/functions that f1 and f2 need to know about/call
...
};
class ode_solver : public its_a_class{
double (its_a_class:: *f)(double, double);
...
};
my_class foo;
ode_solver s;
...
s.f = & foo.f1;
s.solve;
...
s.f = &foo.f2;
s.solve;
etc.
Would this work? But, it's ridiculous, right? There's not a better
way?

Hi, instead of us trying to determine your program requirements and
write example code that will fit it properly, I think it is better to
just teach you about calling a pointer to a member function because it
is possible to do so.

Here is a guide to doing that:

http://www.parashift.com/c++-faq-lit...o-members.html

Good Luck with that :)

Feb 24 '07 #9

P: n/a

I am aware that it is possible to have a pointer to a member
function. However, such a pointer must know the name of the class
that contains the member function to which it points. This is what I
am trying to circumvent.

Please do not write example code for me if you don't want to. I just
included sample code and details of my project to give make more
concrete what I am trying to do. In the simplest terms, I would just
like to know if there is a way for class A to call a member function
of class B without class A knowing that the function it is calling is
a member of class B.

Thanks.


On Feb 23, 6:32 pm, Piyo <cybermax...@yahoo.comwrote:
class my_class : public its_a_class{
double f1(double x, double t);
double f2(double x, double t);
...
// lots of data/functions that f1 and f2 need to know about/call
...
};
class ode_solver : public its_a_class{
double (its_a_class:: *f)(double, double);
...
};
my_class foo;
ode_solver s;
...
s.f = & foo.f1;
s.solve;
...
s.f = &foo.f2;
s.solve;
etc.
Would this work? But, it's ridiculous, right? There's not a better
way?

Hi, instead of us trying to determine your program requirements and
write example code that will fit it properly, I think it is better to
just teach you about calling a pointer to a member function because it
is possible to do so.

Here is a guide to doing that:

http://www.parashift.com/c++-faq-lit...o-members.html

Good Luck with that :)

Feb 24 '07 #10

P: n/a
On Fri, 23 Feb 2007 12:36:07 -0800, tbringley wrote:
I am a c++ newbie, so please excuse the ignorance of this question.

I am interested in a way of having a class call a general member
function of another class.

Specifically, I am trying to write an ordinary differential equation
class that would solve a general equation in the form:
dx/dt = f(x,t).

The ode class shouldn't know anything about f, except how to call it.

My first thought was to have a data member that stores a pointer to
the function f like:
double (*f) (double, double);

However, I learned that f could not point to a non-static member
function of a different class. This is bad for me, because I need to
use the solver for functions that are complicated to evaluate and
depend on many parameters. A simple example:

class my_f{ public:
double a;
double f(double x, double t){ return t+x*a;}
};

my_f foo; foo.a = 7;

I would like the ode solver to call foo.f(x,t). I could make

double (my_f::* f)(double, double);

a member of the ode solver, but then I would have to write a new ode
solver for every new class of functions to be used for f or to have
all these derive from some kind of base class, which I would prefer to
avoid.

My question is: is there a simple and elegant way to do this? I would
think that similar issues have been encountered many times before.
Thanks.
How about something like this?

#include <iostream>

class Aclass
{
double a,b;
public:
Aclass(double a_, double b_) : a(a_), b(b_)
{
}

double func1(double x, double t)
{
return a*x+b*t;
}

double func2(double x, double t)
{
return a*x*x+b*t;
}
};

template<typename Tdouble solver(T& obj, double (T::*func)(double,double))
{
double y = (obj.*func)(2.0,3.0);
return y;
}

int main()
{
Aclass aclass(3.0, 4.0);

double y1 = solver(aclass, &Aclass::func1);

std::cout << "y1 = " << y1 << '\n';

double y2 = solver(aclass, &Aclass::func2);

std::cout << "y2 = " << y2 << '\n';
}

Output:
y1 = 18
y2 = 24

--
Lionel B
Feb 24 '07 #11

P: n/a
On Sat, 24 Feb 2007 00:04:12 +0000, Lionel B wrote:
On Fri, 23 Feb 2007 12:36:07 -0800, tbringley wrote:
>I am a c++ newbie, so please excuse the ignorance of this question.

I am interested in a way of having a class call a general member
function of another class.

Specifically, I am trying to write an ordinary differential equation
class that would solve a general equation in the form:
dx/dt = f(x,t).

The ode class shouldn't know anything about f, except how to call it.

My first thought was to have a data member that stores a pointer to
the function f like:
double (*f) (double, double);

However, I learned that f could not point to a non-static member
function of a different class. This is bad for me, because I need to
use the solver for functions that are complicated to evaluate and
depend on many parameters. A simple example:

class my_f{ public:
double a;
double f(double x, double t){ return t+x*a;}
};

my_f foo; foo.a = 7;

I would like the ode solver to call foo.f(x,t). I could make

double (my_f::* f)(double, double);

a member of the ode solver, but then I would have to write a new ode
solver for every new class of functions to be used for f or to have
all these derive from some kind of base class, which I would prefer to
avoid.

My question is: is there a simple and elegant way to do this? I would
think that similar issues have been encountered many times before.
Thanks.

How about something like this?
[snip]

Sorry, you wanted your solver to be a class... try something
along these lines:

#include <iostream>

class Aclass
{
double a,b;

public:
Aclass(double a_, double b_) : a(a_), b(b_)
{
}

double func1(double x, double t)
{
return a*x+b*t;
}

double func2(double x, double t)
{
return a*x*x+b*t;
}
};

class Solver
{
double c,d;

public:
Solver(double c_, double d_) : c(c_), d(d_)
{
}

template<typename Tdouble solve(T& obj, double (T::*func)(double,double))
{
double y = (obj.*func)(c,d);
return y;
}
};

int main()
{
Solver solver(2.0,3.0);

Aclass aclass(3.0, 4.0);

double y1 = solver.solve(aclass, &Aclass::func1);

std::cout << "y1 = " << y1 << '\n';

double y2 = solver.solve(aclass, &Aclass::func2);

std::cout << "y2 = " << y2 << '\n';
}

Output:
y1 = 18
y2 = 24

--
Lionel B
Feb 24 '07 #12

P: n/a

Thanks Lionel! That's brilliant.

On Feb 23, 7:14 pm, Lionel B <m...@privacy.netwrote:
On Sat, 24 Feb 2007 00:04:12 +0000, Lionel B wrote:
On Fri, 23 Feb 2007 12:36:07 -0800, tbringley wrote:
I am a c++ newbie, so please excuse the ignorance of this question.
I am interested in a way of having a class call a general member
function of another class.
Specifically, I am trying to write an ordinary differential equation
class that would solve a general equation in the form:
dx/dt = f(x,t).
The ode class shouldn't know anything about f, except how to call it.
My first thought was to have a data member that stores a pointer to
the function f like:
double (*f) (double, double);
However, I learned that f could not point to a non-static member
function of a different class. This is bad for me, because I need to
use the solver for functions that are complicated to evaluate and
depend on many parameters. A simple example:
class my_f{ public:
double a;
double f(double x, double t){ return t+x*a;}
};
my_f foo; foo.a = 7;
I would like the ode solver to call foo.f(x,t). I could make
double (my_f::* f)(double, double);
a member of the ode solver, but then I would have to write a new ode
solver for every new class of functions to be used for f or to have
all these derive from some kind of base class, which I would prefer to
avoid.
My question is: is there a simple and elegant way to do this? I would
think that similar issues have been encountered many times before.
Thanks.
How about something like this?

[snip]

Sorry, you wanted your solver to be a class... try something
along these lines:

#include <iostream>

class Aclass
{
double a,b;

public:
Aclass(double a_, double b_) : a(a_), b(b_)
{
}

double func1(double x, double t)
{
return a*x+b*t;
}

double func2(double x, double t)
{
return a*x*x+b*t;
}

};

class Solver
{
double c,d;

public:
Solver(double c_, double d_) : c(c_), d(d_)
{
}

template<typename Tdouble solve(T& obj, double (T::*func)(double,double))
{
double y = (obj.*func)(c,d);
return y;
}

};

int main()
{
Solver solver(2.0,3.0);

Aclass aclass(3.0, 4.0);

double y1 = solver.solve(aclass, &Aclass::func1);

std::cout << "y1 = " << y1 << '\n';

double y2 = solver.solve(aclass, &Aclass::func2);

std::cout << "y2 = " << y2 << '\n';

}

Output:
y1 = 18
y2 = 24

--
Lionel B

Feb 24 '07 #13

P: n/a

Thanks Lionel! That's brilliant.

On Feb 23, 7:14 pm, Lionel B <m...@privacy.netwrote:
On Sat, 24 Feb 2007 00:04:12 +0000, Lionel B wrote:
On Fri, 23 Feb 2007 12:36:07 -0800, tbringley wrote:
I am a c++ newbie, so please excuse the ignorance of this question.
I am interested in a way of having a class call a general member
function of another class.
Specifically, I am trying to write an ordinary differential equation
class that would solve a general equation in the form:
dx/dt = f(x,t).
The ode class shouldn't know anything about f, except how to call it.
My first thought was to have a data member that stores a pointer to
the function f like:
double (*f) (double, double);
However, I learned that f could not point to a non-static member
function of a different class. This is bad for me, because I need to
use the solver for functions that are complicated to evaluate and
depend on many parameters. A simple example:
class my_f{ public:
double a;
double f(double x, double t){ return t+x*a;}
};
my_f foo; foo.a = 7;
I would like the ode solver to call foo.f(x,t). I could make
double (my_f::* f)(double, double);
a member of the ode solver, but then I would have to write a new ode
solver for every new class of functions to be used for f or to have
all these derive from some kind of base class, which I would prefer to
avoid.
My question is: is there a simple and elegant way to do this? I would
think that similar issues have been encountered many times before.
Thanks.
How about something like this?

[snip]

Sorry, you wanted your solver to be a class... try something
along these lines:

#include <iostream>

class Aclass
{
double a,b;

public:
Aclass(double a_, double b_) : a(a_), b(b_)
{
}

double func1(double x, double t)
{
return a*x+b*t;
}

double func2(double x, double t)
{
return a*x*x+b*t;
}

};

class Solver
{
double c,d;

public:
Solver(double c_, double d_) : c(c_), d(d_)
{
}

template<typename Tdouble solve(T& obj, double (T::*func)(double,double))
{
double y = (obj.*func)(c,d);
return y;
}

};

int main()
{
Solver solver(2.0,3.0);

Aclass aclass(3.0, 4.0);

double y1 = solver.solve(aclass, &Aclass::func1);

std::cout << "y1 = " << y1 << '\n';

double y2 = solver.solve(aclass, &Aclass::func2);

std::cout << "y2 = " << y2 << '\n';

}

Output:
y1 = 18
y2 = 24

--
Lionel B

Feb 24 '07 #14

P: n/a
tb*******@gmail.com wrote:

First things first. You're top-posting (i.e., posting above the text to
which you're replying rather than below or inline) and you seem to be
double posting as well. Both of things will make others less inclined
to help you. (To your credit, you've composed clear and thoughtful
questions, which is always appreciated.)
Thanks for the suggestions everyone. I guess what I had in mind was
something along the lines of:

class ode_solver{
...
double (*f) (double,double);
void solve();
...
};

ode_solver s;
s.f = & arbitraryclass.arbitraryfunction;
s.solve();

This would work perfectly fine if f pointed to a non-member function
-- and this idea is used a lot in C.
Indeed, but think about why this won't work for a member function.
Conceptually when you call member function A::f( x, t), you're really
making a call along the lines of f( A*, x, t) where A* is the "this"
pointer. As you suggested in your original post, f needs to have some
sort of local state and there's no way to make all of that local state
available to some other function if you only give it a function pointer.
>
I will be needing to use the ode_solver with an extremely general set
of functions f that might come from all different kinds of classes.
It is not an option to guarantee that f is a member of a particular
class or has a particular name (i.e. f or operator(double,double)). I
would much prefer if I didn't have to modify the code of
arbitraryclass, if that's possible.
Well that's understandable. In that case you might want to consider
some sort of adapter class that makes an arbitrary third party class
compatible with your solver. Again you can do this via templates or
inheritance, but basically you need wrap a reference to the third party
class inside of some standardized function object and specialize the
function object to call the third party class function. This may
involve some fairly gnarly syntax so I won't embarrass myself by trying
to write sample code on the spot :)
>

It seems like the suggestions are along the lines of that f should be
itself a class. So...

class ode_solver{
TwoArgFunc f;
};

but then...

class my_class{
TwoArgFunc f1;
...
};
No, my suggestion was that my_class derive from TwoArgFunc, not that it
contain such a function. But if you don't have access to the other
classes then this becomes a moot issue.

-Mark
Feb 24 '07 #15

P: n/a
Mark P wrote:
Well that's understandable. In that case you might want to consider
some sort of adapter class that makes an arbitrary third party class
compatible with your solver. Again you can do this via templates or
inheritance, but basically you need wrap a reference to the third party
class inside of some standardized function object and specialize the
function object to call the third party class function. This may
involve some fairly gnarly syntax so I won't embarrass myself by trying
to write sample code on the spot :)
Okay, I was intrigued enough to try this myself. It actually works very
nicely:

#include <iostream>

using namespace std;

// class FcnAdapter: bridges arbitrary function class to Solver

template< typename T>
class FcnAdapter
{
public:
FcnAdapter( T& fcn) : fcn( fcn) {}

double eval( double x, double y);

private:
T& fcn;
};

// class Fcn1

struct Fcn1
{
public:
Fcn1( double d) : d( d) {}

double run( double x, double y) { return x * y / d;}

double d;
};

// specialize eval for Fcn1

template<>
double FcnAdapter<Fcn1>::eval( double x, double y)
{
return fcn.run( x, y);
}

// class Fcn2

struct Fcn2
{
public:
Fcn2( double d) : d( d) {}

double execute( double x, double y) { return (x + y) / d;}

double d;
};

// specialize eval for Fcn2

template<>
double FcnAdapter<Fcn2>::eval( double x, double y)
{
return fcn.execute( x, y);
}


// class Solver

template< typename F>
class Solver
{
public:
Solver( F& f) : f( f) {}

void execute()
{
for( int i = 0; i < 3; ++i)
for( int j = 0; j < 3; ++j)
cout << f.eval( i, j) << endl;
}

private:
F& f; // F is a FcnAdapter
};
// helper fcn for arbitrary base function class.

template< typename T>
void runSolver( T& base)
{
FcnAdapter< Tadapter( base);
Solver< FcnAdapter< T solver( adapter);
solver.execute();
}

// main

int main()
{
Fcn1 f1( 2.1);
Fcn2 f2( 3.5);

cout << "runSolver( f1)" << endl;
runSolver( f1);

cout << endl << "runSolver( f2)" << endl;
runSolver( f2);
}

All you have to do is specialize the FcnAdapter eval function for any
particular function class you have and the rest is handled
automatically. Note the use of a templated function (runSolver) to
automate the template argument deduction (since no deduction is
performed for class templates).

Hope that helps,
Mark
Feb 24 '07 #16

P: n/a
Note that top-posting and double-posting is generally
considered rude on the Usenet. The fact that your problem
is interesting (at least for me) overweights the (probably
unintended) rudeness.

On Feb 24, 1:05 am, tbring...@gmail.com wrote:
Thanks for the suggestions everyone. I guess what I had
in mind was something along the lines of:

class ode_solver{
...
double (*f) (double,double);
void solve();
...

};

ode_solver s;
s.f = & arbitraryclass.arbitraryfunction;
s.solve();

I will be needing to use the ode_solver with an extremely
general set of functions f that might come from all
different kinds of classes.
So basically what you need is ode_solver class you can
stuff pretty much anything that could be representing an
f(x,t) into and f(x,t) implementations that are blissfully
unaware of ode_solver's desires. Sounds like it's time for
Captain Genericity! An adapter template class exposing a
simple interface to ode_solver and hiding the grisly
details of calling the various f(x,t) implementations would
fit the bill, I believe.

The details will vary depending on those f(x,t)
implementations, but consider the following code:

#include <iostream>

// f(x,t) implementations. Blissfully ignorant.
class foo
{ public :
double a_ ;
foo ( ) : a_ ( 1 ) { }
double warble ( double x , double t ) const
{ return t + x * a_ ; } } ;

class bar
{ public :
double a_ ;
bar ( ) : a_ ( 1 ) { }
double goonglify ( double x , double t ) const
{ return t - x * a_ ; } } ;

class xyzzy
{ public :
double a_ ;
mutable double t_ ;
xyzzy ( ) : a_ ( 1 ) , t_ ( 1 ) { }
void t ( double t ) const { t_ = t ; }
double fooble ( double x ) const
{ return t_ - x * a_ ; } } ;

// The generic f(x,t) interface.
class interface_f_x_t
{ public :
virtual double operator ( )
( double x , double t ) const = 0 ; } ;

// ode solver. Blissfully ignorant.
class ode
{ public :
static void solve ( const interface_f_x_t & f )
{ std :: cout << f ( 1.0 , 1.0 ) << std :: endl ; }
} ;

// That's the rug we'll be hiding our dirty little secrets
// under.
template < typename T , typename F >
class f_x_t : public interface_f_x_t
{ public :
f_x_t ( const T & obj , F f ) :
obj_ ( obj ) , f_ ( f ) { }
virtual double operator ( )
( double x , double t ) const = 0 ;
private :
const T & obj_ ;
F f_ ; } ;

template < typename T >
class f_x_t
< T , double ( T :: * ) ( double , double ) const :
public interface_f_x_t
{ public :
typedef
double ( T :: * f_ptr ) ( double , double ) const ;
f_x_t ( const T & obj , f_ptr f ) :
obj_ ( obj ) , f_ ( f ) { }
virtual double operator ( )
( double x , double t ) const ;
private :
const T & obj_ ;
f_ptr f_ ; } ;

template < typename T >
double
f_x_t < T , double ( T :: * ) ( double , double ) const >
:: operator ( ) ( double x , double t ) const
{ return ( obj_ .* f_ ) ( x , t ) ; }

template < typename T >
class f_x_t
< T , double ( T :: * ) ( double ) const :
public interface_f_x_t
{ public :
typedef double ( T :: * f_ptr ) ( double ) const ;
typedef void ( T :: * s_ptr ) ( double ) const ;
f_x_t ( const T & obj , f_ptr f , s_ptr s ) :
obj_ ( obj ) , f_ ( f ) , s_ ( s ) { }
virtual double operator ( )
( double x , double t ) const ;
private :
const T & obj_ ;
f_ptr f_ ;
s_ptr s_ ; } ;

template < typename T >
double
f_x_t < T , double ( T :: * ) ( double ) const >
:: operator ( ) ( double x , double t ) const
{ ( obj_ .* s_ ) ( t ) ; return ( obj_ .* f_ ) ( x ) ; }

// Let's see if it all comes together...
int main ( )
{ foo foo1 ;
bar bar1 ;
xyzzy xyzzy1 ;

f_x_t
< foo , double ( foo :: * ) ( double , double ) const >
f1 ( foo1 , & foo :: warble ) ;
f_x_t
< bar , double ( bar :: * ) ( double , double ) const >
g1 ( bar1 , & bar :: goonglify ) ;
f_x_t
<xyzzy , double ( xyzzy :: * ) ( double ) const >
h1 ( xyzzy1 , & xyzzy :: fooble , & xyzzy :: t ) ;

ode :: solve ( f1 ) ;
ode :: solve ( g1 ) ;
ode :: solve ( h1 ) ;

foo1 . a_ = 5 ;
bar1 . a_ = 5 ;
xyzzy1 . a_ = 5 ;

ode :: solve ( f1 ) ;
ode :: solve ( g1 ) ;
ode :: solve ( h1 ) ; }

Hope this helps a bit.

--
roy axenov

Feb 24 '07 #17

P: n/a

Thanks Mark and Roy. Apologies for the top posting and double
posting. I am not knowledgeable in the ways of usenet.

Those are great ideas, and it seems like I'll be able to get exactly
the functionality I want. Particuarly nice is the idea of a function
interface class that hides all the templating syntax and can be reused
whenever this situation arises (I can think of 3 or 4 examples off the
top of my head just for the ode solver).

I'm beginning to get an idea of the power of templating in c++. And I
was just happy that I didn't have to write separate code for int and
double...

Thanks again to everyone who put time and thought into helping out.

Tom

Feb 24 '07 #18

P: n/a
On Feb 24, 3:47 pm, tbring...@gmail.com wrote:
Thanks Mark and Roy. Apologies for the top posting and double
posting. I am not knowledgeable in the ways of usenet.

Those are great ideas, and it seems like I'll be able to get exactly
the functionality I want. Particuarly nice is the idea of a function
interface class that hides all the templating syntax and can be reused
whenever this situation arises (I can think of 3 or 4 examples off the
top of my head just for the ode solver).

I'm beginning to get an idea of the power of templating in c++. And I
was just happy that I didn't have to write separate code for int and
double...

Thanks again to everyone who put time and thought into helping out.

Tom
if you don't need tigher coupling, consider taking a look at Command
Pattern

Diego

Feb 26 '07 #19

This discussion thread is closed

Replies have been disabled for this discussion.