Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass method of a class into another function in C++?

Say I have a class and a function

class A
{
    int a;
    int b;
    int mul()
    {
        return a+b;
    }
};
...

void func(int af, int bf, int (*fc)())
{
    ...
}

In the main function, the function is supposed to use the methods of class A

int main
{
    A as;
    ...
    func(as.a, as.b, as.mul);
}

However, I can't do that, the compiler keeps telling me that I'm passing

(int&, int&, 'unresolved overloaded function type') 

into a function of candidate

(int, int, void(*)()).

Why is that, and how to pass method of a class into another function?

Oh, I think I should make the problem a little bit clearer. func(...) is actually a function from an algorithm I'm working on. And class A is a model that will use the algorithm to do the simulation. So I don't think I'll specifically use the instance of A in function B, but only pass A's methods and components in and work with them.


Update: Some have mentioned using static methods in class A. However, this is still a partial solution. Using static method mul() will force me to claim a and b both to be static. And if I have to use multiple instances of A, with method a, b different in each instance in my main function, using static variables will simply fail.

So, are there other suggestions on how to fix this without using static variables/methods? I remember in script languages such as python, passing methods of whatever type is basically not an issue. Why can't I do a similar thing in C++? Or are there workarounds in C++ that can help me do this?

like image 514
Chong Avatar asked Sep 15 '25 23:09

Chong


1 Answers

First of all, mul is a member function of A, so you can't invoke it as if it was a global function or a static member function: it needs an object on which the function is invoked:

A::mul(); // ERROR!
A a;
a.mul(); // OK

This said, you could change the definition of func to accept a pointer-to-member-function:

void func(int af, int bf, void (A::*fc)())
//                        ^^^^^^^^^^^^^^^

However, this change alone won't make you progress too much, because you're still not passing the concrete instance of A on which the member function should be invoked. In other words, this would be illegal:

fc(); // ERROR!

To over come this limitation, you could pass a reference or a pointer to an instance of A together to func, and call it as done below:

void func(A* pA, int af, int bf, void (A::*fc)())
{
    ...
    (pA->*func)();
}

However, if func() has the object on which the member function should be invoked passed in as an argument, it is not clear what is the purpose of af and bf.

Possibly, if your mul() member function does not need to work on any concrete instance of A, and still you want to make it a member of A, you could declare it as static:

class A
{
    int a;
    int b;
    static void mul();
//  ^^^^^^
};

This would make your original call to func() compile. However, in this case it is not clear whether this would make sense, since the fact that mul() accept no arguments suggests that it is supposed to work on the a and b members of the object it is invoked on.

like image 187
Andy Prowl Avatar answered Sep 18 '25 22:09

Andy Prowl