我试图将 lambda 函数存储在队列中以便稍后执行。为了做到这一点,我试图将参数包隐藏在 lambda 中而不丢失作用域,这样我仍然可以访问上层作用域中传递的参数。 遗憾的是我无法编译它,因为参数包与 const 限定符不匹配。 我希望通过查看以下代码更容易理解我想要完成的任务。 (我使用的是 c++17,而不是 c++20)。 我认为我误解了如何正确转发可变参数包,因为正如我现在所做的那样,对 const 的绑定(bind)引用将丢弃限定符。
遗憾的是,期望函数 lambda 中的参数为 const 并不是一种选择。
std::queue<std::function<void()>> fcts;
template<typename F >
auto push_fct(F &task) -> void {
// Do things
fcts.push(std::move(std::function<void()>(task)));
}
template<typename F, typename... A>
auto push_fct(F& task , A&... args) -> void {
push_fct( [task, args...] { task(args...);});
}
auto main() -> int {
auto functional = [&](class_a & a, class_b & b) {
a.memberFct();
b.memberFunction(123);
}
class_a instance_a;
class_b instance_b;
push_fct(functional, instance_a, instance_b);
return 0;
}
最佳答案
发生的情况是,这里[task, args...]
引用丢失了; task, args...
通过值捕获,在不可变的 lambda 中,它另外变成 const
,随后不能绑定(bind)到中的非常量引用调用[&](class_a & a, class_b & b)
。
您可以通过引用捕获引用。不用担心它们的生命周期 - 引用已折叠,原始引用将被捕获 ( source )。
template<typename F>
auto push_fct(F&& task) -> void {
// Do things
fcts.emplace(std::forward<F>(task));
}
template<typename F, typename... A>
auto push_fct(F& task, A&... args) -> void {
push_fct([&task, &args...]{ task(args...); });
}
关于c++ - 在 lambda 中正确转发参数包而不丢弃限定符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66663303/