复杂元组捕获

时间:2017-09-16 10:13:00

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

我正在试图找出一种方法来捕获可以由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

1 个答案:

答案 0 :(得分:3)

在:

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;
};

将左值作为参考值和rvalues按值存储。