如何转换 lambda 函数参数并将其存储在 std::function 中

Gas*_*sim 2 c++ lambda c++11

我有一个存储在向量中的函数列表:

std::vector<std::function<void(uint32_t)>> mFunctions;
Run Code Online (Sandbox Code Playgroud)

我想添加一个函数作为公共 API,它接受不同的参数,但将其转换为 uint32_t:

enum class MyHandle : uint32_t { Null = 0; };


void addFunction(std::function<void(MyHandle)> &&fn) {
  mFunctions.push_back(fn);
}
Run Code Online (Sandbox Code Playgroud)

我怎样才能实现这个目标?

chr*_*nte 6

您只需自己进行转换,然后通过将转换后的参数包装在 lambda 中来调用该函数:

void addFunction(std::function<void(MyHandle)> fn) {
    mFunctions.push_back([fn = std::move(fn)](uint32_t value) {
        fn(MyHandle{ value });
    });
}
Run Code Online (Sandbox Code Playgroud)

既然我们已经这样做了,我建议该addFunction方法应该是在回调参数上参数化的模板。这样您就可以防止类型擦除的大量开销,因为您没有两层std::function

template <std::invocable<MyHandle> F>
void addFunction(F&& fn) {
    mFunctions.push_back([fn = std::forward<F>(fn)](uint32_t value) {
        std::invoke(fn, MyHandle{ value });
    });
}
Run Code Online (Sandbox Code Playgroud)

如果您无法访问 C++20,它将如下所示:

template <typename F>
void addFunction(F&& fn) {
    mFunctions.push_back([fn = std::forward<F>(fn)](uint32_t value) {
        std::invoke(fn, MyHandle{ value });
    });
}
Run Code Online (Sandbox Code Playgroud)

这是实际代码的示例