J'essaie de stocker dans un std::tuple
un 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 je m'efforce de 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
ou 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 comment le faire pour répartir un appel de fonction.
La motivation réelle de cette démarche est un peu plus complexe et il s'agit surtout d'un exercice d'apprentissage. Vous pouvez supposer que le tuple m'est fourni par contrat par une autre interface, et qu'il ne peut donc pas être modifié, mais que le désir de le décomposer en un appel de fonction est le mien. Cela exclut l'utilisation de std::bind
comme un moyen bon marché de contourner le problème sous-jacent.
Quel est le moyen le plus simple de lancer l'appel en utilisant la fonction std::tuple
ou un meilleur moyen d'obtenir le même résultat net en stockant/transférant certaines valeurs et un pointeur de fonction jusqu'à un point futur arbitraire ?
5 votes
Pourquoi ne pouvez-vous pas simplement utiliser
auto saved = std::bind(f, a, b, c);
... puis plus tard, appelez simplementsaved()
?0 votes
Ce n'est pas toujours mon interface à contrôler. Je reçois un tuple par contrat de quelqu'un d'autre et je veux en faire quelque chose par la suite.