2015-08-02 22 views
5

Mam dwie funkcje: f i g. f oblicza zwracaną wartość asynchronicznie i zwraca przyszłość. Teraz, na podstawie kilku wartości zwracanych f, chcę wywołać g, ale chcę się upewnić, że obliczenia wartości f zdarzają się równolegle.Rozpakowywanie pakietu parametrów w języku C++

Rozważmy następujący kod:

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 
} 

Jak mogę rozpakować typy od zmiennej liczbie argumentów szablonu T funkcji call_wrapper?

+1

Wystarczy popatrzeć na 'std :: tuple'. Idealnie nadaje się do przechowywania obiektów z paczkami variadic. – Quentin

Odpowiedz

5

[Edycja2: Chyba źle zrozumiałem pytanie, zapomniałem, że subzero chce zwrócić std::future s i po prostu myślałem, że jedynym problemem była składnia pakietu parametrów. Mamy nadzieję, że przy użyciu funkcji pomocnika jak w mojej pierwszej edycji powinno działać chociaż]

Można po prostu zrobić:

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

chyba że źle, co chcesz zrobić.

Edit1: jeśli chcesz zrobić coś innego, można podzielić funkcję w dwóch połączeń, tak:

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

To powinno zadziałać, ponieważ w nim będzie obliczana właściwa wartość, ale obliczenia "f" nie będą dokonywane równolegle. Pierwszy argument zostanie obliczony, następnie drugi i tak dalej. – subzero

+0

który mógłby działać ... tworząc 'przyszłość' w jednej funkcji i wywołując' get() 'w innym – subzero

+0

Ach, zapomniałem o" równolegle ", przepraszam, może wtedy działałaby druga forma, ale ja Nie jestem pewien, wydaję, że stwierdzam, że źle zrozumiałem część twojego pytania. – Caninonos

3

Oto szybkie rozwiązanie przechowywania std::future s w 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