Re: passing member function pointers to a function
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< T> adapter( 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