【问题标题】:properly forward a parameter pack in a lambda without discarding qualifiers在不丢弃限定符的情况下正确转发 lambda 中的参数包
【发布时间】:2021-03-16 20:57:08
【问题描述】:

我正在尝试将 lambda 函数存储在队列中以便稍后执行它们。为了做到这一点,我试图在不丢失作用域的情况下将参数包隐藏在 lambda 中,这样我仍然可以在上层作用域中访问传递的参数。 遗憾的是,我无法编译它,因为参数包与 const 限定符不匹配。 我希望通过查看以下代码更容易理解我想要完成的工作。 (我使用的是 c++17,而不是 c++20)。 我想我误解了如何正确转发可变参数包,因为正如我现在所做的那样,对 const 的绑定引用将丢弃限定符。

很遗憾,不能期望函数式 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;
}

【问题讨论】:

  • 重要的问题是,instance_ainstance_b 在 lambda 稍后执行之前是否存在,或者您是否要将它们的副本与 lambda 一起存储?或者这就是你所说的“不失范围”?
  • 对不起,如果我没有说清楚。仅当两个实例都存在且有效时才会执行 lambda。但是 lambda 是在另一个线程中调用的,所以我必须通过引用传递它们,这样我仍然可以访问成员函数

标签: c++


【解决方案1】:

发生的情况是,这里[task, args...] 的引用丢失了; task, args... 由值捕获,在非可变 lambda 中另外变为 const,随后在对 [&amp;](class_a &amp; a, class_b &amp; b) 的调用中无法绑定到非 const 引用。

您可以通过引用捕获引用。不用担心它们的生命周期 - 引用已折叠,原始引用将被捕获 (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...); });
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-31
    • 1970-01-01
    • 1970-01-01
    • 2018-06-24
    • 2019-09-23
    • 2014-02-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多