Your Browser is not longer supported

Please use Google Chrome, Mozilla Firefox or Microsoft Edge to view the page correctly
Loading...

{{viewport.spaceProperty.prod}}

Grundlegende Aspekte

&pagelevel(4)&pagelevel

Die Sprache C++ beinhaltet das Konzept der Templates. Ein Template ist die Beschreibung einer Klasse oder Funktion, die als Modell für eine Familie von abgeleiteten Klassen oder Funktionen dient. So kann man z.B. ein Template für eine Stack-Klasse schreiben und als Integer-Stack, Float-Stack oder einen Stack für einen beliebigen benutzerdefinierten Typ verwenden. Im Quellcode könnten diese dann beispielsweise Stack<int>, Stack<float> und Stack<X> genannt werden. Aus der einmaligen Beschreibung eines Templates für einen Stack im Quellcode kann der Compiler Instanzen des Templates für jeden benötigten Typ generieren.

Die jeweilige Instanz eines Klassen-Templates wird immer dann erzeugt, wenn sie während der Übersetzung benötigt wird.
Demgegenüber werden die Instanzen von Funktions-Templates sowie von Elementfunktionen oder statische Datenelemente eines Klassen-Templates (im Folgenden Template-Einheiten genannt) nicht notwendigerweise sofort erzeugt. Die wichtigsten Gründe hierfür sind:

  • Bei Template-Einheiten mit externer Linkage (Funktionen und statische Datenelemente) ist es wichtig, programmweit nur eine einzige Kopie der instanziierten Template-Einheit zu haben.

  • Es ist erlaubt, eine Spezialisierung für eine Template-Einheit zu schreiben. Das heißt, der Programmierer kann für einen bestimmten Datentyp eine spezielle Implementierung anbieten, die an Stelle der generierten Instanz benutzt wird. Im Sprachmodus C++ V3 muss diese nicht gesondert deklariert werden. Da der Compiler beim Übersetzen einer Referenz auf eine Template-Einheit nicht wissen kann, ob es Spezialisierungen dieser Template-Einheit in einer anderen Übersetzungseinheit gibt, darf er nicht sofort die Instanz generieren.

  • Template-Funktionen, die nicht referenziert werden, sollen gemäß des C++ Standard nicht übersetzt und auf Fehler überprüft werden. Deshalb sollte die Referenz auf ein Klassen-Template nicht bewirken, dass automatisch alle Elementfunktionen dieser Klasse instanziiert werden.

Bestimmte Template-Einheiten wie z.B. Inline-Funktionen werden immer instanziiert, wenn sie benutzt werden.

Die oben aufgeführten Anforderungen machen deutlich, dass der Compiler, wenn er für die gesamte Instanziierung verantwortlich ist („automatische“ Instanziierung), diese nur programmweit sinnvoll durchführen kann. Das heißt, er kann die Instanziierung von Template-Einheiten erst dann durchführen, wenn ihm der Quellcode sämtlicher Übersetzungseinheiten des Programms bekannt ist.

Mit dem C/C++-Compiler steht ein Instanziierungs-Mechanismus zur Verfügung, bei dem die automatische Instanziierung zum Binde-Zeitpunkt (und zwar mithilfe eines „Prälinkers“) durchgeführt wird. Nähere Einzelheiten siehe Abschnitt "Automatische Instanziierung“.

Für die explizite Kontrolle der Instanziierung durch den Programmierer stehen durch Optionen wählbare Instanziierungsmodi sowie #pragma-Anweisungen zu Verfügung:

  • Die Optionen zur Auswahl der Instanziierungsmodi lauten -T auto, -T none, -T local und -T all . Sie sind ausführlich im Abschnitt "Template-Optionen“ beschrieben.

  • Die Instanziierung einzelner Templates oder auch einer Gruppe von Templates kann mit folgenden #pragma-Anweisungen gesteuert werden:

    • Das Pragma instantiate bewirkt, dass die als Argument angegebene Template-Instanz erzeugt wird. Dieses Pragma kann analog zu dem C++-Sprachmittel für explizite Instanziierungsanforderungen template declaration verwendet werden. Siehe auch Beispiel im Abschnitt "Bibliotheken und Templates".

    • Das Pragma do_not_instantiate unterdrückt die Instanziierung der als Argument angegebenen Template-Instanz. Typische Kandidaten für dieses Pragma sind Template-Einheiten, für die spezifische Definitionen (Spezialisierungen) bereitgestellt werden.

    • Das Pragma can_instantiate ist ein Hinweis für den Compiler, dass die als Argument angegebene Template-Instanz in der Übersetzungseinheit erzeugt werden kann, aber nicht muss. Dieses Pragma wird im Zusammenhang mit Bibliotheken benötigt und wird nur im automatischen Instanziierungsmodus ausgewertet. Siehe auch Beispiel im Abschnitt "Bibliotheken und Templates".

    Die genaue Syntax und allgemeine Regeln zu diesen Pragmas finden Sie im C/C++-Benutzerhandbuch [4], Abschnitt „Pragmas zur Steuerung der Template-Instanziierung“.

  • Durch die eingegebenen (in die Source eingemischten) „expliziten Instanziierungsanweisungen“ ist eine explizite Kontrolle möglich. Diese „expliziten Instanziierungsanweisungen“ können über -T etr_file_all bzw. -T etr_file_assigned (siehe Abschnitt "Generieren von expliziten Template-Instanziierungsanweisungen (ETR-Dateien)“) generiert und dann vom Benutzer in die Sourcen eingebracht werden.

Wichtige Hinweise

Die bei diesem Compiler voreingestellte Methode zur Template-Instanziierung (automatische Instanziierung durch den Prälinker und implizites Inkludieren) ist auch die von uns empfohlene Methode. Von der Möglichkeit, über Optionen steuerbar, von diesem voreingestellten Verfahren abzuweichen, sollte nur in Ausnahmefällen Gebrauch gemacht werden und nur bei genauester Kenntnis der gesamten Applikation einschließlich aller definierten und benutzten Templates.

Implizites Inkludieren: Das implizite Inkludieren darf nicht ausgeschaltet werden (mit -K no_implicit_include), wenn Templates aus der C++-V3-Bibliothek (SYSLNK.CRTE.STDCPP) benutzt werden, da in diesem Fall Definitionen nicht gefunden werden.

Andere Instanziierungsmodi als -T auto : Hier besteht die Gefahr, dass unbefriedigte Externverweise (-T none), Duplikate (-T all) oder ggf. Ablauffehler (-T local) auftreten können.