Search code examples
c++function-pointerspointer-to-membermember-functions

Passing a class-member function to a global function as argument


I am trying to pass a member function of class A to a global function as parameter. What must I do to make this work? Also, is this a good idea? Context: I want to do this because (the synonym) doSomething(...) is a very general function that is used in main() as well as in different classes. Thus I can avoid to have several copies of the same code in my Project. What are alternatives (if it's not optimal)?

#include <iostream>
using namespace std;

double doSomething(int i, double (*f)(double)) { return (*f)(i); }

class A{
public:
    A(double x) : number(x) {}
    double times(double i) { return ::doSomething(i, &A::multiply);} //calles the global function and gives a member function as parameter
    double multiply(double i) {return number*i;}
private:
    double number;
};

int main() {

    A obj(5.0);
    cout << obj.times(3.5) <<endl;

    return 0;
}

Compiler complains:

../src/test5.cpp: In member function ‘double A::times(double)’:
../src/test5.cpp:17:63: error: cannot convert ‘double (A::*)(double)’ to ‘double (*)(double)’ for argument ‘2’ to ‘double doSomething(int, double (*)(double))’
  double times(double i) { return ::doSomething(i, &A::multiply);} //calles the global function and gives a parameter member function as parameter
                                                               ^
../src/test5.cpp:17:65: warning: control reaches end of non-void function [-Wreturn-type]
  double times(double i) { return ::doSomething(i, &A::multiply);} //calles the global function and gives a parameter member function as parameter

Solution

  • Your doSomething function expects a free function pointer (free function means non-member function). You try to pass a member function pointer to it. This will not work. Why? When you have a free function, say void f(double), you can simply call it:

    f(3.14);
    

    on the other hand, when you have a member (and non-static) function, to call it you need an object, e.g.:

    obj.m(3.14);
    

    and you cannot call a member function without an object. So a member function cannot be used interchangeably with free function, since they are called in different way. Think about the (*f)(i) call in the doSomething function - what would be the A object for multiply to call upon?

    Your design needs rethinking. If you want to share code, maybe you need some class hierarchy and the common code in the base class?