解除绑定lambda事件处理程序
如何取消绑定我绑定的事件处理程序,如下所示?解除绑定lambda事件处理程序
MyFrame::MyFrame()
{
Bind(wxEVT_COMMAND_MENU_SELECTED,
[](wxCommandEvent&) {
// Do something useful
},
wxID_EXIT);
}
非常感谢您的第一个答案。我已经添加了一些附加信息。
通过使用具体的Functor解除事件处理程序的可能性被记录并且工作正常,但是如果使用C++ 11 lambda样式绑定某些事件,则以后没有Functor availibale可以调用unbind方法。如果相应的wxEvtHandler
应该被破坏,这会造成麻烦。
有没有“窍门”。 。 。如果没有,我没有看到一个真正的用例绑定使用lambda仿函数。 希望我错了。 。 。
非常感谢
Hacki
不能解除绑定时调用绑有拉姆达,为你的榜样。如果你存储了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);
};
}
为什么会这样?根据评论,你必须使用函子的地址来解除绑定。您按值捕获,所以'DoUnbind'有一个lambda的新副本,它不会与最初绑定的地址具有相同的地址。 –
wxWidget's documentation指定Unbind
作品仿函数(lambda表达式和也)的确切方式:
目前仿函数由它们的地址相比,遗憾的是不正确的,如果相同的地址是工作重用于两个不同的函子对象。
所以,如果你想可靠Unbind
一些仿函数,你应该保存在由Bind
和Unbind
呼叫站点共享一个特殊的地方函子,然后通过完全相同的对象这两个函数(他们需要const-references尽管文件没有反映出来)。
这适用于lambdas和函子,所以它甚至不是C++ 11特有的。如果你想Unbind
的东西,这东西应该有一个固定的地址在内存中。因此,它应该有一个名称。这有点杀死了lambda的美丽。
所以,这应该工作:
static auto event_handler = [](wxCommandEvent&) {
// Do something
};
// ...
Bind(..., event_handler, ...);
// ...
Unbind(..., event_handler, ...);
但是,即使这不(或做,这取决于你的运气与临时变量的位置):
struct EventHandler {
void operator()(wxCommandEvent&) const {
// Do something
}
};
// ...
Bind(..., EventHandler(), ...);
// ...
Unbind(..., EventHandler(), ...);
当程序执行完毕,所有事件处理程序将从所有控件中解除绑定。即使对于lambda来说也是如此。
这是非常罕见的,你需要解除用户代码内的东西,但如果你做@Caleth的答案将工作。
不幸的是,目前没有办法做到这一点,你需要将你的lambda存储在一个对象中以给它一个标识,
auto const handler = [](wxCommandEvent&) { ... };
// To bind it:
Bind(wxEVT_MENU, handler, wxID_EXIT);
// To unbind it:
Unbind(wxEVT_MENU, handler, wxID_EXIT);
的可能的复制[wxWidgets的:作为其触发事件解除绑定(http://stackoverflow.com/questions/18955287/wxwidgets-unbind-event-as-its-triggered) – CamFerry
@CamFerry,没有它是不。解绑定函数需要事件处理函数名称,并且这里没有带lambda的名称。它可能是C++ 11中的一些东西...... – Igor