I can't bind a non-static member function to a callback.
I have to bind the test2 class member function here() to test1 member callBack which is a std::function, but I could not find way to do this. Anyone can suggest me if you have any idea.
Show in code
#include <iostream>
#include <stdint.h>
#include <functional>
using namespace std;
class test1{
public:
typedef std::function<void()> callback_function_t;
callback_function_t callBack;
void setCallback(callback_function_t _callBackfn){
callBack = std::move(_callBackfn);
}
void check(void){
callBack();
}
};
class test2{
public:
void here(){
cout << "safsafsdf" << endl;
}
};
int main(){
test1 t1;
test2 t2;
t1.setCallback(t2.here); // Can't Works
return 0;
}
must be set in test1 callback.
The issue is that when creating the std::function you have also to provide the instance of the class the member function has to be invoked on. The other answer uses std::bind, which is a possible solution.
I would suggest using a lambda function as an alternative, for readability:
t1.setCallback([&t2](){t2.here();});
Note that here you are capturing t2 as a reference, so you must ensure that t2 is alive when t1 uses the callback.
Alternatively you can capture by value (making a copy)
t1.setCallback([t2]() mutable {t2.here();});
and you need the mutable keyword to allow the call of a non-const qualified member function
Finally you can also move t2 inside the lambda, avoiding a copy
t1.setCallback([t2 = std::move(t2)]() mutable {t2.here();});
this is the generalized capture, available from C++14. In your specific example using the std::move will hardly make any difference, but in general, if the object is complex, this might be of use.
The syntax you're using for binding the this pointer to t1 isn't correct. You can't simply write t2.here in order to get a function which, when called, is essentially the same as t2.here().
One possible solution is to bind the this object via std::bind(), e.g.
t1.setCallback(std::bind(&test2::here, t2));
But keep in mind, this creates a copy of t2 inside the function object finally stored inside t2.callBack. Modifications to t2 don't affect t1.callBack. If you're sure t1 always outlives t2, you can also create a reference
t1.setCallback(std::bind(&test2::here, std::ref(t2)));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With