C++ 解除lambda事件处理程序的绑定
如何解除已绑定的事件处理程序的绑定,如下所示C++ 解除lambda事件处理程序的绑定,c++,c++11,wxwidgets,C++,C++11,Wxwidgets,如何解除已绑定的事件处理程序的绑定,如下所示 MyFrame::MyFrame() { Bind(wxEVT_COMMAND_MENU_SELECTED, [](wxCommandEvent&) { // Do something useful }, wxID_EXIT); } 非常感谢你的第一个答案。我添加了一些附加信息 使用一个具体的函数来解开事件处理程序的可能性被记录下来,并且工作得很好,但是
MyFrame::MyFrame()
{
Bind(wxEVT_COMMAND_MENU_SELECTED,
[](wxCommandEvent&) {
// Do something useful
},
wxID_EXIT);
}
非常感谢你的第一个答案。我添加了一些附加信息
使用一个具体的函数来解开事件处理程序的可能性被记录下来,并且工作得很好,但是如果你使用C++ 11 lambda样式来绑定一些事情,那么以后就没有调用函数的绑定函数AviiBayle。如果相应的
wxEvtHandler
被销毁,则会导致问题
有“把戏”吗。如果没有,我看不到使用lambda函子绑定的真正用例。
希望我错了
非常感谢Hacki例如,当绑定调用具有lambda时,无法解除绑定。如果存储lambda,则可以从中解除绑定,例如
class MyFrame
{
...
std::function<void()> DoUnbind;
}
MyFrame::MyFrame()
{
auto DoSomethingUseful = [](wxCommandEvent&) {
// Do something useful
};
Bind(wxEVT_COMMAND_MENU_SELECTED,
DoSomethingUseful,
wxID_EXIT);
DoUnbind = [DoSomethingUseful](){
Unbind(wxEVT_COMMAND_MENU_SELECTED,
DoSomethingUseful,
wxID_EXIT);
};
}
类MyFrame
{
...
std::函数DoUnbind;
}
MyFrame::MyFrame()
{
自动dosomethingusseve=[](wxCommandEvent&){
//做些有用的事
};
绑定(已选择wxEVT命令菜单),
有意义的,
wxID_出口);
DoUnbind=[dosomethingusseve](){
解除绑定(已选择wxEVT命令菜单),
有意义的,
wxID_出口);
};
}
指定解除绑定
对函子(以及lambda)的确切方式:
目前,函子是通过它们的地址进行比较的,不幸的是,如果对两个不同的函子对象重复使用相同的地址,则地址不能正常工作
因此,如果您想可靠地解除绑定
某个函子,应该将该函子保存在一个特殊的位置,该位置由绑定
和解除绑定
调用站点共享,然后将完全相同的对象传递给这两个函数(尽管文档没有反映它们)
这适用于lambda和functor,因此它甚至不是特定于C++11的。如果你想解除绑定某个东西,这个东西应该在内存中有一个固定的地址。因此,它应该有一个名字。这在一定程度上扼杀了兰博达斯的美丽
因此,这应该是可行的:
static auto event_handler = [](wxCommandEvent&) {
// Do something
};
// ...
Bind(..., event_handler, ...);
// ...
Unbind(..., event_handler, ...);
但即使这样也不行(或者,这取决于你在临时变量位置上的运气):
当程序完成执行时,所有事件处理程序将与所有控件解除绑定。即使是兰博达斯也是如此
您很少需要在用户代码中解除绑定某些内容,但如果您通过@Caleth进行操作,则答案将有效。不幸的是,目前无法做到这一点,您将需要将lambda存储在对象中以给它一个标识,例如
auto const handler = [](wxCommandEvent&) { ... };
// To bind it:
Bind(wxEVT_MENU, handler, wxID_EXIT);
// To unbind it:
Unbind(wxEVT_MENU, handler, wxID_EXIT);
可能是@CamFerry的副本,不,不是。解除绑定函数采用事件处理程序functor名称,但此处没有lambda的名称。它可能是C++11中的某些东西……为什么会这样呢?根据这里的注释,您必须使用函子的地址来解除绑定。您通过值捕获,因此
DoUnbind
有一个新的lambda副本,该副本的地址与最初绑定的地址不同。
auto const handler = [](wxCommandEvent&) { ... };
// To bind it:
Bind(wxEVT_MENU, handler, wxID_EXIT);
// To unbind it:
Unbind(wxEVT_MENU, handler, wxID_EXIT);