【发布时间】:2016-06-08 05:00:39
【问题描述】:
是否可以重新绑定 std::function 以指向相同的函数但具有不同的对象实例?
假设我有一个对象,它的 std::function 绑定到另一个函数,但如果该对象被复制到另一个实例,我想将 std::function 重新绑定到那个新实例,而不是旧实例。
#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 的包装器来存储其他信息。
【问题讨论】:
-
是如何具体做这件事的问题,还是如何让这个概念在代码中工作?我的意思是,还有其他方法可以正确设置 EventHandler。例如,构造函数可以只是 std::bind(&EventHandler::HandleEvent, this);。还有其他选择,但我不清楚您的目标是什么。
-
更多的是关于如何让这个概念在代码中发挥作用。为了清楚起见,我想我可能过于简化了这个例子。我正在使用的实际代码库与对象具有父子关系。当一个父级被复制时,它的子级也被复制。我需要迁移孩子的 std::functions 以指向新实例而不是指向原始实例。
-
让我先说我可能会尝试找到一种不同的方式来组织事情,然后用我要说的来解决这个问题。这听起来像是一个设计问题,可能有一个更简单的解决方案。但是,您可以创建一个模板包装器来存储将在函数中绑定的指向成员的指针。然后,在您的赋值运算符中,您使用指向成员的指针作为目标和“this”作为实例进行绑定。这样做的唯一原因是如果你想让它通用。如果它总是相同的功能,我会重新绑定它。
-
我的意思是更简单的解决方案是:您可以让子对象具有“设置回调”函数或“初始化父对象”或类似的东西。当您进行分配时,您复制所有子对象并告诉他们将其父对象设置为新实例。或类似的东西。如果您愿意,请告诉我更多详细信息,我们可以进一步讨论。
-
你不只是想要一个指向成员函数的指针吗?
标签: c++ c++11 std-function