0

I have two classes A and B. And I want to call the member function of class B from class A while passing a member function of A to said function of B. The setting:

class B {
    public:
        int dopristep(std::function<int(int,int)> f, double t, double h);
    };

class A {
public:
    
    void run();
    int g(int,int);
    B* mB;
};

void A::run() {

    ires         = mB->dopristep(&g,  T, h)   
}

int A::g(int,int){
//do something
}

I tried with std::bind and std::function definitions. But it didn't work since it requires a static member function somehow. ( I am aware that there are similar questions here. But almost all of them reside these calls in the main or inside only one class) The most similar case I could find which didn't help was here.

Can anyone please help me on how I can implement this ?

ERROR:reference to non-static member function must be called

Astraeus
  • 61
  • 9
  • Can you modify `B::func` or is it fixed? – Erlkoenig Jul 22 '20 at 08:30
  • 1
    `int*f()` declares `f` as a non-member function that takes no arguments and return a *pointer* to an `int`. Perhaps you wanted `int (*f)()`? Or considering how you use `func`, perhaps `int (A::*f)(int, int)`? – Some programmer dude Jul 22 '20 at 08:31
  • B::func is not fixed it was meant as a reference that here I want to pass the function from A. Sorry for the misunderstanding. – Astraeus Jul 22 '20 at 08:32
  • Does this answer your question? [Using generic std::function objects with member functions in one class](https://stackoverflow.com/questions/7582546/using-generic-stdfunction-objects-with-member-functions-in-one-class) – Erlkoenig Jul 22 '20 at 08:33
  • 3
    A pointer to a *non*-member function (like `int (*f)()`) is vastly different from a pointer to a (non-static) member function (like `&A::g`). That's because (non-static) member functions have a hidden first argument that is the `this` pointer. I suggest you use [`std::function`](https://en.cppreference.com/w/cpp/utility/functional/function) instead of function pointers, and use [lambdas](https://en.cppreference.com/w/cpp/language/lambda) instead of passing functions directly. – Some programmer dude Jul 22 '20 at 08:33
  • `func` takes a free function pointer, but `A::run` is a member function. Why dont you simply call `mB->run()`? and please include the error message in the question – 463035818_is_not_an_ai Jul 22 '20 at 08:34
  • There is no need to have a `std::function` argument. Learn how to pass functors via templates and then using `std::bind` should work. – IS4 Jul 22 '20 at 08:36
  • I updated the Question with more of the actual code and the Error Message. @Erlkoenig sadly not since I dont have the namespace in the other class. – Astraeus Jul 22 '20 at 08:42
  • @IllidanS4wantsMonicaback Could you give me an example how to implement this way? – Astraeus Jul 22 '20 at 08:43
  • The problem mentioned by the error message is that you need to fully qualify member function pointers. Instead of `&g` you need to use `&A::g`. But that will lead to other errors, as the `std::function` signature doesn't match that of `A::g`. – Some programmer dude Jul 22 '20 at 08:43
  • The signatures `int(double, double *, double *, double *)` does not match the one of `g`, so that can't work. – Erlkoenig Jul 22 '20 at 08:44
  • You can do `mB->dopristep([&] (int a, int b) { return g(a, b); }, T, h);` just as the linked question shows. – Erlkoenig Jul 22 '20 at 08:45
  • @Erlkoenig updated it since it doesnt matter what I pass there, just wanted to make it simple. – Astraeus Jul 22 '20 at 08:45
  • @Erlkönig thats exactly what fixed it. Thank you! If you make an answer I can accept it. – Astraeus Jul 22 '20 at 08:47

1 Answers1

3

As explained here, pass a lambda that calls the function on the enclosing A instance:

mB->dopristep([&] (int a, int b) { return g(a, b); }, T, h);

Additionally, you could modify dopristep to accept a functional which will avoid some overhead:

template <typename F>
int dopristep(F&& f, double t, double h);
Erlkoenig
  • 2,664
  • 1
  • 9
  • 18