我想知道这是否是一种可接受的编写回调的方法:
存储回调:
struct EventHolder {
std::function<void()> Callback;
EventTypes::EventType Type;
};
std::vector<Events::EventHolder> EventCallbacks;
方法定义:
void On(EventType OnEventType,std::function<void()>&& Callback)
{
Events::EventHolder NewEvent;
NewEvent.Callback=std::move(Callback);
NewEvent.Type=OnEventType;
EventCallbacks.push_back(std::move(NewEvent));
}
绑定(bind)事件:
Button->On(EventType::Click,[]{
// ... callback body
});
我最大的问题是关于按值传递回调。这是一种有效的方法吗?
最佳答案
这是一种非常有效的存储事件处理程序的方法。
但是,我想指出一些有关添加回调的函数签名的细节。您担心按值传递它而不是按引用传递。在您的示例中,您目前有:
void On(EventType OnEventType,std::function<void()>&& Callback)
这很好,只要你只将它绑定(bind)到右值。但是,除非有特殊原因要禁止它,否则我建议您始终使用一种方法,该方法通过值或左值引用接受参数,并在必要时添加右值引用版本作为补充。
没有采用左值引用的方法意味着您的代码当前将无法编译,因为:
std::function<void()> func([](){/*something clever*/});
// Do something necessary with func, perhaps logging or debug prints.
Button->On(EventType::Click, func);
为简单起见,无论何时选择如何传递值,您都可以简单地遵循以下准则:
- 如果您需要一个拷贝或打算修改传入的值,而不想更改实际传递的对象:按值传递。
- 如果您打算修改传入的值,并希望这些更改影响实际传递的对象:通过引用传递。
- 如果您不想更改传递的对象,但认为避免复制是有益的:通过 const 引用传递。
- 如果您通过值、引用或 const 引用获取参数,并且相信可以利用输入参数是临时的知识来实现有值(value)的优化:也允许通过右值引用传递。
关于c++ - 将 lambda 函数作为回调传递和存储,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15652761/