variadic template mit Funktionspointer
-
Hallo zusammen,
ich versuche ein Template zu schreiben, das einen Funktionspointer als non-type template Parameter und eine variable Anzahl an type Parametern akzeptiert. Das Problem: Die Signatur der Funktion, die ich als Pointer übergeben möchte hängt von den type Parametern ab.
Mit einer fixen Anzahl von type Parametern (hier 1) funktioniert es folgendermaßen:
template<class T0, void (*FN)(T0)> struct Caller { void call(T0 arg0) { (*FN)(arg0); } } void callFn(int arg) { // do something } int main() { Caller<int, callFn> caller; caller.call(6); return 0; }
Wie gesagt, dieses Beispiel zeigt den Fall für 1 type Parameter. Ich brauche aber eine variable Anzahl von type Parametern.
Zusätzliche Rahmenbedingung: ich bin auf C++11 beschränkt.Ist das was ich machen möchte überhaupt möglich, und wenn ja wie?
Danke vorweg!
-
Du suchst wohl Parameter Pack.
Gab neulich erst einen Beitrag dazu: Funktionstemplate in Klassentemplate mit Parameterpacks.
-
@Th69 Danke für die schnelle Antwort.
Parameter Packs sind mir prinzipiell bekannt, mein Problem ist eher, dass ich diese nur am Ende der Templateparameter-Liste anfügen kann, sie aber schon für die Signatur des Funktionspointers brauche.Folgendes Beispiel funktioniert nicht weil ARGS am Ende stehen muss:
template<class ...ARGS, void (*FN)(ARGS...)> struct Caller { // ... }
Und das funktioniert nicht weil er ARGS an der Stelle noch nicht kennt:
template<void (*FN)(ARGS...), class ...ARGS> struct Caller { // ... }
-
OK, jetzt verstehe ich dein Problem.
Generell solltest du aber direkte Funktionszeiger vermeiden - und stattdessenstd::function
verwenden, s.a. Function pointers should not be used as function parameters.Aber evtl. helfen C++ and function pointers und Wrap a function pointer in C++ with variadic template.
PS: Außerdem habe ich noch How to Pass a Variadic Pack as the First Argument of a Function in C++ gefunden (habe jetzt aber nicht evaluiert, ob dies auch für Template-Klassen/-Strukturen funktioniert).
-
@MicroC sagte in variadic template mit Funktionspointer:
template<class ...ARGS, void (*FN)(ARGS...)> struct Caller { // ... }
Wie wär's mit
template <class... ARGS> struct Caller { template <void void (*FN)(ARGS...)> struct Impl { // ... }; }
Bessere Namen darfst du dir überlegen
-
@Th69 Die Artikel sind sehr gut, danke! Habe viel hin und her überlegt mit dieser decltype Variante, allerdings ist das ohne Macros immer redundante Tipparbeit und ich versuche Macros so gut es geht zu vermeiden.
-
@hustbaer nested templates... genial! Danach habe ich gesucht, danke!