Problem mit templates
-
Folgende Situation
Ich habe zwei Funktionen f, g mit derselben Signatur. Ich will nun bewerkstelligen, dass ich mit templates die eine oder die andere aufrufen kann:
template <????> void foo() { // hier soll abhängig von ???? f oder g aufgerufen werden }Wie mache ich das?
-
Eine mögliche Variante:
struct call_f_tag {}; struct call_g_tag {}; template<> void foo<call_f_tag>() { f(); } template<> void foo<call_g_tag>() { g(); } // Aufruf: foo<call_f_tag>(); foo<call_g_tag>();(ungetestet)
Die iterator_tags funktionieren auf ähnliche Art und Weise.
-
Geht es auch so, dass ich die Funktion foo nur einmal definiere?
-
Ich würde die Funktionen als Funktoren anlegen, dann ist das recht einfach:
class f { void operator() (void) { /* * */ } }; class g { void operator() (void) { /* * */ } }; template<typename T> void foo() { T funk; funk(); } // Aufruf: foo<g>(); foo<f>();
-
Warum soll es denn ein template sein? Übergib doch einen Funktionszeiger. Oder einen bool "call_f".
void foo(bool call_f) { if(call_f) f(); else g(); }Das ganze geht auch als template

template <bool call_f> void foo() { if(call_f) f(); else g(); }Ansonsten ist Spezialisierung (wie von templater gezeigt) ein üblicher Weg.
-
Man kann auch Funktionszeiger oder -referenzen als Template-Parameter verwenden.
Ich ziehe allerdings die Funktor-Variante vor, wenn sonst nichts dagegen spricht.p.S.:
Die "tag" Variante von "templater" macht IMO Sinn, wenn man das Template "zumachen" will, also dem User die Möglichkeit nehmen jeden beliebigen Funktor/Funktionszeiger zu übergeben.