# function pointers and member functions

• 03-18-2002
thor
function pointers and member functions
I have not been able to find the best (if any satisfactory) solution to the following issue which essentially boils down to how best to have a function (or member function) return a function (pointer).

More concretely:

I have an integration function which as one of its parameter takes a funtion of one variable (say 3+2*x), i.e. the parameter has the form double f(double);

The user can via an interface specify the coefficients to the one parameter function, let's say a and b in the equation a+b*x.

How do I construct a function which takes two parameters (a and b) as input and returns a funtion (pointer) of one variable, namely a+b*x.

OR alternatively, how do I construct a class which as it's constructor takes two parameters (a and b) and provide a means for creating and returning a function of one variable, namely a+b*x. If a+b*x is constructed as a member function, it seems I can't use this member function to pass into my integration routine? And if it is somehow possible, would it create a lot of overhead?

This must be a common sort of problem but I have not been able to find what is a good solution.
• 03-18-2002
SilentStrike

Code:

``` class SingleVariableFunction { public:         virtual float evaulate(float x)=0;         ~SingleVariableFunction(); }; class QuadraticFunction : public SingleVariableFunction { public:         QuadraticFunction(float a, float b, float c); // trivial implmeentation omitted..         float evaulate(float x) {                 return x*(a*x + b) + c;         } private:         float a, b, c; };```
• 03-19-2002
thor
I'm not sure that solves the problem (?)

I need somehow to get hold of the function which takes one parameter and pass it into my integration routine which has the form
double trapzd(double func(const double), const double a, const double b, const int n)

Let qf be an instance of QuadraticFunction.
I want somehow to get hold of qf.evaluate (which is a function of one variable). But I can't do that since evaluate is a member function and I get the error 'Taking address of the bound function ...'

How can I do it?
• 03-19-2002
SilentStrike
You don't need function pointers. Use the polymorphic behavior of the evualate method to perform the integration.

Change the floats to doubles in the signature of both SingleVariableFunction and QuadtraticFunction.

IE,

Code:

```#include <iostream> class SingleVariableFunction { public:  virtual double evaluate(double x)=0;  // print method might be nice as well  virtual ~SingleVariableFunction() { } }; class QuadtraticFunction: public SingleVariableFunction { public:  QuadtraticFunction(double a_, double b_, double c_) {   a = a_;   b = b_;   c = c_;  }  virtual ~QuadtraticFunction() { }  virtual double evaluate(double x) {   return x*(a*x + b) + c;  } private:  double a, b, c; }; double trapezoidalIntegration(SingleVariableFunction* func, double lowerLim, double upperLim, int numIterations) {  double integralSum=0.0;  double deltaX = (upperLim - lowerLim) / (double) numIterations;  double x = lowerLim;  // can be optimized... only half the calls are really needed, but the loop gets messier and I don't want to think :)  for ( int i = 0; i < numIterations; i++) {   integralSum += func->evaluate(x) + func->evaluate(x+ deltaX);   x+=deltaX;  }  integralSum = integralSum * deltaX/ 2;  return integralSum; } int main() {  SingleVariableFunction* func = new QuadtraticFunction(1, 0, 0);  std::cout << "Integral of 1*x^2 from 0 to 2 is " << trapezoidalIntegration(func, 0, 2, 1000) << std::endl;  delete func;  return 0; }```
Edit:
Evaluate is the hardest damned word to spell in the English langauge :).
• 03-19-2002
thor
Thanks for spelling it out for me!

It exactly does the job.

In know in Lisp (Scheme) it's very easy and natural to have a function return another function (using the lambda function) but in c++, as you show me, one needs to bring out some of the more heavy machinery.
• 03-19-2002
SilentStrike
Heh.. never used Lisp, heard it's pretty painful though.