0

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
Robert
  • 10,403
  • 14
  • 67
  • 117
dani
  • 3,677
  • 4
  • 26
  • 60

4 Answers4

1

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?

Wojtek Surowka
  • 20,535
  • 4
  • 44
  • 51
1

With C++11 you might do:

#include <functional>

typedef std::function<double (double)> do_something_function;
double doSomething(double i, do_something_function f) { return f(i); }

class A{
    public:
    A(double x) : number(x) {}
    double times(double i) {
        do_something_function f = [this] (double i) {
            return this->multiply(i);
        };
        return ::doSomething(i, f);
    }
    double multiply(double i) {
        return number * i;
    }

    private:
    double number;
};
0

The way you call a non-static function member of a class via pointer differs from the way you do it on freestanding function because a pointer to instance is needed.

#include <iostream>
using namespace std;

class A;
typedef double (A::*f)(double);
double doSomething(double i, f p, A* ap);

class A {
public:

    A(double x) : number(x) {
    }

    double times(double i) {
        return ::doSomething(i, &A::multiply, this);
    } //calles the global function and gives a member function and pointer to A

    double multiply(double i) {
        return number*i;
    }
private:
    double number;
};

double doSomething(double i, double (A::*fp)(double), A* ap) {
    return (ap->*fp)(i);  // call *fp on *ap
}

int main() {

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

    return 0;
}

example

4pie0
  • 29,204
  • 9
  • 82
  • 118
  • In your example i would still need to declair the type of object `doSomething` wants. This means i would still need a copy of the same code for other object. I think Wojtek Surowka was right about to rethink my design. Thank you for your answer. – dani Mar 28 '14 at 15:32
0

it is tricky of programing -- convert a non-static member function into a global function refer to the source code : https://github.com/shenxiaolong-code/processInternalExplorer/blob/master/sources/SystemExplorer/include/SystemExplorer/callback_cpp2c.h

Shen Tony
  • 19
  • 3
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/late-answers/31080143) – user904963 Feb 22 '22 at 17:00