Templatespezialisierung

Wenn’s mal wieder was besonderes sein soll: Templates sind ja eigentlich als generische Möglichkeit zur Generierung von Code ausgelegt. Bei aller Verallgemeinerung hat man allerdings manchmal das Bedürfnis, für einzelne Parametertypen etwas besonderes zu machen. Dafür gibt es dann Templatespezialisierung: findet der Compiler bei der Instanziierung eines Templates eine spezialisierte Variante für einen speziellen Typ, dann nimmt er diese, statt der allgemeinen Variante. Dabei kann sich das Verhalten (oder im Falle von Klassentemplates: die Struktur) der spezialisierten Variante durchaus deutlich vom allgemeinen Template unterscheiden.

Video

Code

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

Erklärung

Das print-Template in der allgemeingültigen Variante hat unter meinem Compiler ein Problem: immer wenn ich einen bool ausgeben lassen will, kriege ich 0 und 1, statt true und false. Das ist etwas unschön, aber Templatespezialisierung kann hier Abhilfe schaffen. Wir spezialisieren in Zeile 8 das Template, indem wir es wieder hinschreiben, die Template-Parameterliste aber leer lassen und stattdessen wie bei der Instanziierung den konkreten Typ, für den wir spezialisieren, hinter den Templatenamen. Instanziieren wir nun in der main-Funktion das Template, so nimmt der Compiler in den Zeilen 15 und 17 die allgemeine Variante und instanziiert sie für int und double. In Zeile 16 hingegen wählt der Compiler die spezialisierte Variante aus und gibt damit auch korrekterweise “true” und “false” aus.