Sto cercando di memorizzare in un std::tuple
numero variabile di valori, che verranno successivamente utilizzati come argomenti per una chiamata a un puntatore a funzione che corrisponde ai tipi memorizzati.
Ho creato un esempio semplificato che mostra il problema che sto lottando per risolvere:
#include <iostream>
#include <tuple>
void f(int a, double b, void* c) {
std::cout << a << ":" << b << ":" << c << std::endl;
}
template <typename ...Args>
struct save_it_for_later {
std::tuple<Args...> params;
void (*func)(Args...);
void delayed_dispatch() {
// How can I "unpack" params to call func?
func(std::get<0>(params), std::get<1>(params), std::get<2>(params));
// But I *really* don't want to write 20 versions of dispatch so I'd rather
// write something like:
func(params...); // Not legal
}
};
int main() {
int a=666;
double b = -1.234;
void *c = NULL;
save_it_for_later<int,double,void*> saved = {
std::tuple<int,double,void*>(a,b,c), f};
saved.delayed_dispatch();
}
Normalmente per problemi che coinvolgono std::tuple
o modelli variadici, scriverei un altro modello template <typename Head, typename ...Tail>
per valutare ricorsivamente tutti i tipi uno per uno, ma non vedo un modo per farlo per inviare una chiamata di funzione.
La vera motivazione per questo è un po 'più complessa ed è per lo più solo un esercizio di apprendimento comunque. Si può presumere che mi sia stata consegnata la tupla per contratto da un'altra interfaccia, quindi non può essere modificata ma il desiderio di decomprimerlo in una chiamata di funzione è mio. Questo esclude l'utilizzo std::bind
come un modo economico per eludere il problema sottostante.
Qual è un modo pulito per inviare la chiamata utilizzando il std::tuple
, o un modo migliore alternativo per ottenere lo stesso risultato netto di memorizzare / inoltrare alcuni valori e un puntatore a funzione fino a un punto futuro arbitrario?
auto saved = std::bind(f, a, b, c);
... e poi chiamaresaved()
?