2015-08-02 10 views
5

Ho due funzioni f e g. f calcola il valore restituito in modo asincrono e restituisce un futuro. Ora, in base a diversi valori di ritorno di f, voglio chiamare g, ma voglio assicurarmi che i calcoli dei valori di f avvengano in parallelo.Unpacking Parameter Pack in C++

Si consideri il seguente codice:

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 
} 

Come posso scompattare i tipi dal modello variadic T della funzione call_wrapper?

+1

Dai un'occhiata a 'std :: tuple'. È perfetto per la memorizzazione di oggetti pack variabili. – Quentin

risposta

5

[Modifica2: Credo di aver frainteso la domanda, ho dimenticato che il subzero voleva restituire std::future s e pensavo semplicemente che l'unico problema era la sintassi del parametro pack. Speriamo che, utilizzando una funzione di supporto come nella mia prima modifica dovrebbe funzionare anche se]

Si può semplicemente fare:

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

A meno che non ho capito male quello che si vuole fare.

Edit1: se si vuole fare qualcosa di diverso, è possibile dividere la funzione in due chiamate, in questo modo:

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

Questo dovrebbe funzionare, in quanto calcolerà il valore corretto, ma i calcoli di 'f' non avverranno in parallelo. Il primo argomento verrà calcolato, quindi il secondo e così via. – subzero

+0

che potrebbe funzionare ... rendendo il 'future's in una funzione e chiamando' get() 's in un altro – subzero

+0

Ah, ho dimenticato" in parallelo ", mi spiace, forse il secondo modulo funzionerebbe allora, ma io Non sono sicuro, modifico per affermare che ho frainteso una parte della tua domanda. – Caninonos

3

Ecco una soluzione rapida memorizzazione dei std::future s in un std::tuple:

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