将std :: function绑定到不同对象实例的相同函数 [英] Binding a std::function to the same function of a different object instance
问题描述
是否可以重新绑定std :: function以指向相同的函数,但具有不同的对象实例?
Is it possible to rebind a std::function to point to the same function but with a different object instance?
如果我的对象具有一个std :: function绑定到另一个函数,但是如果将该对象复制到另一个实例,我想将std :: function重新绑定到该新实例而不是旧实例。
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;
}
我很乐意拥有std :: function的包装器来存储
I'm open to having a wrapper of the std::function to store additional information.
推荐答案
以下代码引入了 binding_function< R(Args ...)>
(类似于 function< R()>
),并且参数在构造后可以随时重新绑定(假设它不是 nullptr
)。
The following code introduced a binding_function<R(Args...)>
, which is called like function<R()>
, and arguments can be rebind anytime after it constructed (assuming it was not nullptr
).
#include <functional>
#include <tuple>
#include <utility>
#include <memory>
#include <iostream>
template <typename T>
class binding_function;
template <typename R, typename... Args>
class binding_function<R(Args...)> : std::function<R()>
{
using base_function = std::function<R(Args...)>;
using binded_function = std::function<R()>;
base_function base;
public:
binding_function() = default;
template <typename BaseF, typename... TArgs>
binding_function(BaseF&& f, TArgs&&... args)
: base(std::forward<BaseF>(f)) {
rebind(std::forward<TArgs>(args)...);
}
template <typename... TArgs>
void rebind(TArgs&&... args)
{
static_cast<binded_function&>(*this) =
std::bind(base, std::forward<TArgs>(args)...);
}
using binded_function::operator();
};
class EventHandler
{
public:
// change type of OnEvent to binding_function
binding_function<int(EventHandler)> OnEvent;
// others remain the same
};
int main()
{
EventHandler a(4);
// first binding
a.OnEvent = {&EventHandler::HandleEvent, a};
EventHandler b(a);
b.Num = 5;
b.OnEvent.rebind(b); // rebinding
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;
}
这篇关于将std :: function绑定到不同对象实例的相同函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!