2017-09-16 2 views
0

J'essaie de trouver un moyen de capturer un pack variadique qui peut être constitué de références de valeurs l et r et capturer les valeurs r par valeur tout en capturant les valeurs l par référence pour une utilisation ultérieure (d'où le test asynchrone). J'ai essayé ce qui suit:Capture de tuple complexe

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

Cependant, cela génère une valeur indéfinie lors de l'exécution des valeurs lambda. Les lvalues ​​lambda sortent le 50 désiré sans construction de copie (peut être utilisé avec de gros objets). Existe-t-il un moyen de capturer la valeur r par valeur, sans copier construire des objets qui sont passés par l-valeur de référence ne sachant pas quel genre de combinaison de valeurs l et r j'obtiendrai?

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

Lien à l'exemple coquille http://cpp.sh/336lv

Répondre

3

Dans:

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

grâce à la magie de référence effondrement, T est un type de référence lvalue pour les arguments qui sont lvalues, et un non-référence tapez pour les arguments qui sont rvalues. Vous voulez donc:

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

pour stocker les valeurs lues comme références et valeurs par valeur.

+0

Oui! C'est ce dont j'avais besoin, génial, j'avais peur d'avoir besoin d'une grande fonction méta pour changer les types de valeur en retour en références l-value ou quelque chose, ce genre de choses peut devenir vraiment déroutant quand vous devez capturer en lambdas .... –