英文:
How can I convert a lambda function arguments and store it in std::function
问题
我有一个存储在向量中的函数列表:
std::vector<std::function<void(uint32_t)>> mFunctions;
我想要添加一个函数作为公共API,该函数接受不同的参数但将其转换为uint32_t:
enum class MyHandle : uint32_t { Null = 0; };
void addFunction(std::function<void(MyHandle)>&& fn) {
mFunctions.push_back(fn);
}
我该如何实现这一目标?
英文:
I have a list of functions stored in a vector:
std::vector<std::function<void(uint32_t)>> mFunctions;
I want to add a function as a public API that accepts a different argument but casts it to uint32_t:
enum class MyHandle : uint32_t { Null = 0; };
void addFunction(std::function<void(MyHandle)> &&fn) {
mFunctions.push_back(fn);
}
How can I achieve this?
答案1
得分: 6
你只需要自己进行转换并用lambda包装参数来调用函数:
void addFunction(std::function<void(MyHandle)> fn) {
mFunctions.push_back([fn = std::move(fn)](uint32_t value) {
fn(MyHandle{ value });
});
}
既然我们已经在这个过程中,我建议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 });
});
}
如果你无法使用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 });
});
}
英文:
You simply have to do the cast yourself and invoke the function with the casted argument by wrapping it in a lambda:
void addFunction(std::function<void(MyHandle)> fn) {
mFunctions.push_back([fn = std::move(fn)](uint32_t value) {
fn(MyHandle{ value });
});
}
Since we're already at it, I would recommend that the addFunction
method should be a template parameterized on the callback argument. This way you prevent a lot of overhead of the type erasure, since you don't have two layers of 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 });
});
}
If you don't have access to C++20 it would look like this:
template <typename F>
void addFunction(F&& fn) {
mFunctions.push_back([fn = std::forward<F>(fn)](uint32_t value) {
std::invoke(fn, MyHandle{ value });
});
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论