取消绑定 lambda 事件处理程序
Unbinding a lambda event handler
如何解除绑定的事件处理程序,如下所示?
MyFrame::MyFrame()
{
Bind(wxEVT_COMMAND_MENU_SELECTED,
[](wxCommandEvent&) {
// Do something useful
},
wxID_EXIT);
}
非常感谢第一个回答。我添加了一些额外的信息。
通过使用具体的 Functor 取消绑定事件处理程序的可能性已记录在案并且工作正常,但如果您使用 C++ 11 lambda 样式来绑定某物,则以后没有可用的 Functor 来调用取消绑定方法。如果相应的 wxEvtHandler
应该被销毁,这会造成麻烦。
有没有"trick"。 . .如果不是,我看不到使用 lambda 仿函数进行绑定的真实用例。
希望我错了。 . .
非常感谢
哈基
如您的示例,当对 Bind 的调用有 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);
};
}
wxWidget's documentation 指定 Unbind
为仿函数(以及 lambda)工作的确切方式:
Currently functors are compared by their address which, unfortunately, doesn't work correctly if the same address is reused for two different functor objects.
所以,如果你想 Unbind
一些可靠的仿函数,你应该把仿函数保存在一个特殊的地方,由 Bind
和 Unbind
调用站点共享,然后通过两个函数的完全相同的对象(它们采用 const-references 尽管文档没有反映它)。
这适用于 lambda 和仿函数,因此它甚至不是特定于 C++11 的。如果你想 Unbind
something,这个 something 在内存中应该有一个固定的地址。因此,它应该有一个名称。这有点破坏了 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);
如何解除绑定的事件处理程序,如下所示?
MyFrame::MyFrame()
{
Bind(wxEVT_COMMAND_MENU_SELECTED,
[](wxCommandEvent&) {
// Do something useful
},
wxID_EXIT);
}
非常感谢第一个回答。我添加了一些额外的信息。
通过使用具体的 Functor 取消绑定事件处理程序的可能性已记录在案并且工作正常,但如果您使用 C++ 11 lambda 样式来绑定某物,则以后没有可用的 Functor 来调用取消绑定方法。如果相应的 wxEvtHandler
应该被销毁,这会造成麻烦。
有没有"trick"。 . .如果不是,我看不到使用 lambda 仿函数进行绑定的真实用例。 希望我错了。 . .
非常感谢
哈基
如您的示例,当对 Bind 的调用有 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);
};
}
wxWidget's documentation 指定 Unbind
为仿函数(以及 lambda)工作的确切方式:
Currently functors are compared by their address which, unfortunately, doesn't work correctly if the same address is reused for two different functor objects.
所以,如果你想 Unbind
一些可靠的仿函数,你应该把仿函数保存在一个特殊的地方,由 Bind
和 Unbind
调用站点共享,然后通过两个函数的完全相同的对象(它们采用 const-references 尽管文档没有反映它)。
这适用于 lambda 和仿函数,因此它甚至不是特定于 C++11 的。如果你想 Unbind
something,这个 something 在内存中应该有一个固定的地址。因此,它应该有一个名称。这有点破坏了 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);