【问题标题】:Complex tuple capture复杂元组捕获
【发布时间】:2017-09-16 10:12:59
【问题描述】:

我试图找出一种方法来捕获一个可变参数包,它可以由 l 和 r 值引用组成,并按值捕获 r 值,同时通过引用捕获 l 值以供以后使用(因此异步测试)。我尝试了以下方法:

#include <iostream>
#include <tuple>
#include <future>

template<typename... T>
auto bar(T&&... values)
{
    return [tup = std::forward_as_tuple(values...)](){
        std::cout << std::get<0>(tup) << std::endl;
    };
}

int lValue = 50;

int main ()
{
    auto rvalues = bar(50);
    auto lvalues = bar(lValue);

    auto futureR(std::async(rvalues));
    auto futureL(std::async(lvalues));
    futureR.get();
    futureL.get();
    return 0;
}

然而,这在执行 rvalues lambda 时会输出一个未定义的值。左值 lambda 输出所需的 50 而无需复制构造(可能与大对象一起使用)。是否有某种方法可以按值捕获 r 值,而无需复制构造由 l 值引用传递的对象,不知道我会得到什么样的 l 和 r 值组合?

auto mixedValues = bar(50, lValue);
auto futureMixed(std::async(mixedValues));

链接到示例 shell http://cpp.sh/336lv

【问题讨论】:

    标签: c++ lambda c++14 variadic-templates forwarding-reference


    【解决方案1】:

    在:

    template<typename... T>
    auto bar(T&&... values)
    {
        return [tup = std::forward_as_tuple(values...)](){
            std::cout << std::get<0>(tup) << std::endl;
        };
    }
    

    由于引用折叠的魔力,T 是左值参数的左值引用类型,以及右值参数的非引用类型。你因此想要:

    return [tup = std::tuple<T...>(std::forward<T>(values)...)](){
        std::cout << std::get<0>(tup) << std::endl;
    };
    

    将左值存储为引用,并按值存储右值。

    【讨论】:

    • 是的!这就是我所需要的,太棒了,我担心我需要一些丑陋的元函数来将左值类型更改回左值引用或其他东西,当你必须捕获到 lambdas 时,这些东西会变得非常混乱......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-30
    • 1970-01-01
    • 2014-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多