c++ - 将 lambda 函数作为回调传递和存储

标签 c++ c++11 callback lambda

我想知道这是否是一种可接受的编写回调的方法:

存储回调:

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/

相关文章:

javascript - 如何将 canvas.toblob() 回调转换为 Observable

javascript - 回调和高阶函数 Javascript

c# - c++ wchar数组到c#

c++ - 为什么比较范围枚举是合法的

c++ - 带有 llvm 和 clang 的架构 x86_64 的 undefined symbol

c++ - 将任何函数作为模板参数传递

c++ - 对数组使用unique_ptr,如何在 Debug模式下查看每个值 "local"或 "watch"标签

c++ - 具有非均匀缩放的 3x3 矩阵旋转

c++ - 减少冗长 : inserting elements into map

android-fragments - 当您想在 android studio 3.6.3 中创建新片段时,复选框 "include interface callbacks"在哪里