2015-08-02 8 views
5

Ich habe zwei Funktionen f und g. f berechnet den Rückgabewert asynchron und gibt eine Zukunft zurück. Nun, basierend auf mehreren Rückgabewerten von f, möchte ich g aufrufen, aber ich möchte sicherstellen, dass die Berechnungen der Werte von f parallel passieren.Auspacken des Parameterpakets in C++

Betrachten Sie den folgenden Code ein:

template <typename T> 
std::future<T> f(T& t); 

template <typename... T> 
void g(T&&... t) 

template <typename... T> 
void call_wrapper(T&&... t) { 
    auto f1 = f(t1); // How do I set the values of f1... fn 
    auto f2 = f(t2); 
    ... 
    g(f1.get(), f2.get()....); // How do I call g 
} 

Wie kann ich die Typen aus der variadische Vorlage T der call_wrapper Funktion entpacken?

+1

Werfen Sie einen Blick auf 'std :: tuple'. Es ist perfekt zum Aufbewahren von variablen Pack-Objekten. – Quentin

Antwort

5

[Edit2: Ich denke, ich missverstanden die Frage, ich vergaß subzero wollte std::future s zurückgeben und dachte einfach, dass das einzige Problem war die Parameter Pack-Syntax. Hoffentlich mit einer Helferfunktion wie in meinem ersten bearbeiten soll allerdings arbeiten]

Sie können einfach tun:

template <typename... T> 
void call_wrapper(T&&... t) { 
    g(f(std::forward<T>(t)).get()...); 
} 

Wenn ich nicht falsch verstanden, was Sie tun wollen.

Edit1: wenn Sie etwas anderes tun wollen, können Sie die Funktion in zwei Anrufe, wie folgt aufteilen:

template<typename... T> 
void helper(T&&... t) { 
    // ... 
    g(std::forward<T>(t).get()...); 
} 

template <typename... T> 
void call_wrapper(T&&... t) { 
    helper(f(std::forward<T>(t))...); 
} 
+0

Das sollte funktionieren, da darin der richtige Wert berechnet wird, aber die Berechnungen von 'f' werden nicht parallel ausgeführt. Das erste Argument wird berechnet, dann das zweite und so weiter. – subzero

+0

das könnte funktionieren ... machen die 'future's in einer Funktion und rufen die' get() 's in einem anderen – subzero

+0

Ah, ich habe" parallel "vergessen, sorry, vielleicht würde das zweite Formular dann funktionieren, aber ich bin nicht sicher, ich werde bearbeiten, um zu sagen, dass ich einen Teil Ihrer Frage missverstanden habe. – Caninonos

3

Hier ist eine schnelle Lösung ist die std::future s in einem std::tuple Lagerung:

template <class T, std::size_t... Idx> 
void callG(T &tuple, std::index_sequence<Idx...>) { 
    g(std::get<Idx>(tuple).get()...); 
} 

template <typename... T> 
void call_wrapper(T&&... t) { 
    auto results = std::make_tuple(f(std::forward<T>(t))...); 
    callG(results, std::index_sequence_for<T...>{}); 
} 

Live on Coliru