Funktionstemplates

Nicht nur Klassen können aus Templates gebaut werden, sondern auch bei Funktionen ist das möglich. Sieht im Grunde genommen wie beim Erstellen von Klassentemplates aus, generiert aber neuen Code für eine bestimmte Funktion. Dabei kann der Compiler bestimmte Templateparameter auch noch automatisch ableiten.

Video

Code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#include <iostream>
 
template <typename T> void print(T const &t)
{
  std::cerr << "Wert: " << t << std::endl;
}
 
int main()
{
  print(10);
  print(true);
  print(12.5);
}

Erklärung

Die Syntax zur Definition von Funktionstemplates ist quasi identisch zu der von Klassentemplates: das Schlüsselwort template, dann die Parameterliste und dann geht’s ganz normal mit einer Funktionsdeklaration weiter. Die Typparameter können ganz normal als Typen im Template verwendet werden, genau wie bei den Klassentemplates.

Eine interessante zusätzliche Funktionalität bieten die Funktionstemplates allerdings: wenn sich, wie in unserem Beispiel, ein Templateparameter als Typ in der Parameterliste der Funktion wiederfindet, dann kann der Compiler diesen Templateparameter automatisch ableiten. Hier im Beispiel sieht man das in der main-Funktion an den Aufrufen des print-Templates: anders als bei Klassentemplates haben wir hier den Templateparameter nicht explizit angegeben. So weiß aber der Compiler bspw. in Zeile 10, dass der Wert 10 vom Typ int ist. Daraus kann er ableiten, dass das print-Template genau dann am besten passt, wenn dessen Parameter T durch int ersetzt wird und sich so in der Parameterliste der Funktion ein int const & ergibt. Diese Ersetzung führt er durch und instanziiert damit das Template für uns automatisch.

Prinzipiell können wir diese Entscheidung natürlich auch hinschreiben und damit den Compiler überstimmen. Um bspw. print mit long, statt int zu instanziieren, würden wir einfach schreiben print<long>(10). Der Compiler instanziiert das Template dann mit long, stellt fest, dass in der Parameterliste dann ein long const & gebraucht wird und konvertiert die 10 (die ja eigentlich ein int ist) automatisch dorthin.