Is it possible to rebind a std::function to point to the same function but with a different object instance?
Say if I have an object that has a std::function that is bound to another function, but if that object was copied to another instance, I'd like to rebind the std::function to that new instance instead of the old instance.
#include "stdafx.h"
#include <iostream>
#include <functional>
class EventHandler
{
public:
int Num;
std::function<int()> OnEvent;
EventHandler (int inNum)
{
Num = inNum;
}
EventHandler (const EventHandler& other)
{
Num = other.Num;
OnEvent = other.OnEvent; //TODO: Need some way to redirect the std::function to the new instance rather than having the delegate point to the original object's handler.
}
int HandleEvent ()
{
return Num;
}
};
int main()
{
EventHandler a(4);
a.OnEvent = std::bind(&EventHandler::HandleEvent, a);
EventHandler b(a);
b.Num = 5;
//Uncommenting the line below is a manual way of redirecting event handler to the new instance.
//b.OnEvent = std::bind(&EventHandler::HandleEvent, b);
int aResult = a.OnEvent();
int bResult = b.OnEvent();
//This will print out 4 and 4 instead of 4 and 5 since b is still bound to a's event handler.
std::cout << "aResult=" << aResult << " bResult=" << bResult << '\n';
return 0;
}
I'm open to having a wrapper of the std::function to store additional information.
The following code introduced a
binding_function<R(Args...)>
, which is called likefunction<R()>
, and arguments can be rebind anytime after it constructed (assuming it was notnullptr
).I extended user1887915's answer to allow functions with parameters:
AFAIK what you are asking is not possible, but I think there is a workaround that you can do:
This prints "aResult=4 bResult=5" as you want. Also, I think by employing a bit more metaprogramming magic, we can try to prettify the syntax.
Let me know if this works for you.
What your event handler does should depend on which instance it is called on. Hence, logically, the correct way of solving the problem is providing the instance as a parameter to the handler function, e.g.
Of course, if your handling function always is a member function, you can simply replace the
std::function
by a pointer-to-member-function.Note that you should properly initialize the
handlingFunction
member in the constructor of yourEventHandler
class, e.g. by setting it to a dummy function.