Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

const function pointers

I'm have some difficulties with function pointers. I have an base class which defines a function pointer that via typedef double (*function)(double *x) const;

  • A quick side question: why does the above typedef not compile?

    Gives the following error: error: ‘const’ and ‘volatile’ function specifiers on ‘function’ invalid in type declaration

For the part below I use typedef double (*function)(double *x). Now each daughter class can implement multiple and different versions of functions of this type. Via an enum I select the function of my choice, which sets my non-member function pointer (defined in the base class) to be initialized by one of these member-function pointers of the daughter class. Here's a code snippet:

The source file of the daughter class:

PndLmdROOTDataModel1D::PndLmdROOTDataModel1D(interpolation_type intpol_type) {
  if(intpol_type == CONSTANT) {
    setModelFunction(&PndLmdROOTDataModel1D::evaluateConstant); 
  }
  else if (intpol_type == SPLINE) {
    setModelFunction(&PndLmdROOTDataModel1D::evaluateSpline);
  }
  else {
    setModelFunction(&PndLmdROOTDataModel1D::evaluateLinear);
  }
}

And the base Class (header file):

class MultiModel1D: public Model1D {
protected:
  function model_func;

public:
  MultiModel1D();
  virtual ~MultiModel1D();

  void setModelFunction(function f);
}

When compiling I get the following error:

note: no known conversion for argument 1 from ‘double (PndLmdROOTDataModel1D::*)(double*)’ to ‘function {aka double (*)(double*)}’

I'm using the function pointer, because of speed issues (at least I think this should be faster than constantly running through some switch case). What am I doing wrong? Maybe there is also some design pattern that will serve as a better alternative... Thanks in advance!

Steve

like image 611
steve Avatar asked Nov 29 '22 13:11

steve


2 Answers

That is because there is a fundamental difference between a (free-)function pointer and a member function pointer. You "side question" already contains the hint to the problem. To explain, you can do either this:

typedef double (SomeClass::*function)(double *x) const;

or

typedef double (*function)(double *x);

but a non-member function can never be declared const on the function level. Those types can not be converted to each other and this is the problem in your code that the compiler is pointing out.

If they could be converted, you would end up with a problem: The member function pointer tells the compiler that it needs an object to be called with, which will be put into this when the member function is called. If the pointer could be casted to a normal function pointer, this object would be missing and probably all parameters would be messed up as a consequence. So, no, you really can't just cast them. The reality is even more complicated (multiple/virtual inheritance), but you get the picture...

like image 192
Daniel Frey Avatar answered Dec 22 '22 20:12

Daniel Frey


For the same reason that we shall not write:

void foo() const
{
   // ...
}

outside of a class declaration. Non-member functions cannot be const.

Your function pointer is a normal function pointer, not a pointer-to-member-function and, as such, const has no meaning there.

like image 33
Lightness Races in Orbit Avatar answered Dec 22 '22 20:12

Lightness Races in Orbit