4

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

steve
  • 133
  • 1
  • 2
  • 10
  • possible duplicate of [pointer to const member function typedef](http://stackoverflow.com/questions/3050805/pointer-to-const-member-function-typedef) – Bo Persson Mar 19 '13 at 17:13
  • The bottom error says it all. Function pointers are not the same as member function pointers. http://liveworkspace.org/code/1iUxos%242 – chris Mar 19 '13 at 17:14
  • ordinary function cannot be const?? – yngccc Mar 19 '13 at 17:14
  • I'm confused. Which bit is your question? You appear to have several. – Lightness Races in Orbit Mar 19 '13 at 17:21
  • Just like member functions aren't the same as functions (remember, member functions have a "hidden" `this` argument), member function pointers aren't the same as function pointers. You are trying to stuff member function pointers into function pointers. – Nik Bougalis Mar 19 '13 at 17:25
  • The const part is understood, thx! But why can't I cast a member function pointer to a non-member function pointer. Why does the compiler care about that? I can see that he says its not the same.. So does that mean the thing I want to do, is just not possible or is there a solution. Making the function pointer a member function pointer in the typedef doesn't help I think, because I have several daughter classes. Hence one member function pointer would be initialized by another type. – steve Mar 19 '13 at 17:41

2 Answers2

16

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...

Daniel Frey
  • 55,810
  • 13
  • 122
  • 180
  • thx for the insanely fast answsers! I got the const part for non-member functions making no sense. But for the second error I took out all of the const. Basically my question would be why can't the compiler cast a member function pointer to a non-member function pointer. – steve Mar 19 '13 at 17:43
  • @steve: I added an explanation. – Daniel Frey Mar 19 '13 at 20:10
8

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.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055