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);