Ich versuche, in einer std::tuple
variierenden Anzahl von Werten zu speichern , die später als Argumente für einen Aufruf eines Funktionszeigers verwendet werden, der den gespeicherten Typen entspricht.
Ich habe ein vereinfachtes Beispiel erstellt, das das Problem zeigt, das ich nur schwer lösen kann:
#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();
}
Normalerweise std::tuple
würde ich bei Problemen mit oder mit variablen Vorlagen eine andere Vorlage schreiben template <typename Head, typename ...Tail>
, um alle Typen nacheinander rekursiv auszuwerten, aber ich sehe keine Möglichkeit, dies für den Versand eines Funktionsaufrufs zu tun.
Die eigentliche Motivation dafür ist etwas komplexer und meistens nur eine Lernübung. Sie können davon ausgehen, dass ich das Tupel vertraglich von einer anderen Schnittstelle erhalten habe, es kann also nicht geändert werden, aber der Wunsch, es in einen Funktionsaufruf zu entpacken, liegt bei mir. Dies std::bind
schließt aus, dass das zugrunde liegende Problem auf billige Weise umgangen wird.
Was ist eine saubere Methode, um den Anruf mit dem zu versenden std::tuple
, oder eine alternative bessere Methode, um das gleiche Nettoergebnis zu erzielen, indem einige Werte und ein Funktionszeiger bis zu einem beliebigen zukünftigen Punkt gespeichert / weitergeleitet werden?
auto saved = std::bind(f, a, b, c);
... dann später einfach anrufensaved()
?