J'essaie de stocker dans un std::tuple
nombre variable de valeurs, qui seront plus tard utilisées comme arguments pour un appel à un pointeur de fonction qui correspond aux types stockés.
J'ai créé un exemple simplifié montrant le problème que j'ai du mal à résoudre:
#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();
}
Normalement, pour les problèmes impliquant std::tuple
des modèles variadiques, j'écrirais un autre modèle, comme template <typename Head, typename ...Tail>
pour évaluer récursivement tous les types un par un, mais je ne vois pas de moyen de le faire pour envoyer un appel de fonction.
La vraie motivation pour cela est un peu plus complexe et c'est surtout juste un exercice d'apprentissage de toute façon. Vous pouvez supposer que le tuple m'a été remis par contrat à partir d'une autre interface, donc ne peut pas être changé, mais que le désir de le décompresser dans un appel de fonction est le mien. Cela exclut l'utilisation std::bind
comme moyen bon marché de contourner le problème sous-jacent.
Quelle est une façon propre de répartir l'appel à l'aide de la std::tuple
, ou une meilleure façon alternative d'obtenir le même résultat net de stockage / transfert de certaines valeurs et d'un pointeur de fonction jusqu'à un point futur arbitraire?
auto saved = std::bind(f, a, b, c);
... puis appeler plus tardsaved()
?