|
Bei C++-Übersetzungen kann die Instanziierung einzelner Templates oder auch einer Gruppe von Templates mit folgenden Pragmas gesteuert werden:
Das Pragma
instantiate
bewirkt, dass die als Argument angegebene Template-Instanz erzeugt wird. Dieses Pragma kann in allen Instanziierungsmodi benutzt werden.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. Dieses Pragma kann in allen Instanziierungsmodi benutzt 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.
Folgende Argumente können mit den Pragmas angegeben werden:
Argument | Beispiele |
Name eines Klassen-Templates |
|
Name einer Elementfunktion |
|
Name eines statischen Datenelements |
|
Deklaration einer Elementfunktion |
|
Deklaration eines Funktions-Templates |
|
Wenn als Argument der Name eines Klassen-Templates angegeben wird (z.B. A<int>
), so hat dies die gleiche Wirkung, als wenn das Pragma für jede Elementfunktion und für jedes statische Datenelement dieses Klassen-Templates angegeben worden wäre. Bei der Instanziierung einer gesamten Klasse kann die Instanziierung von einzelnen Elementfunktionen oder statischen Datenelementen mit dem Pragma do_not_instantiate
unterdrückt werden.
Beispiel
#pragma instantiate A<int> #pragma do_not_instantiate A<int>::f
Für die Instanziierung von Templates müssen die Template-Definitionen in der aktuellen Übersetzungseinheit verfügbar sein. Es führt zu einer Fehlermeldung (ERROR), wenn eine Instanziierung explizit mit dem Pragma instantiate
angefordert wird und keine Template-Definition oder nur eine spezifische Definition (Spezialisierung) vorliegt.
Beispiel
template <class T> void f1(T); // no body provided template <class T> void g1(T); // no body provided template <> void f1(int) { } // specific definition int main() { int i; double d; f1(i); f1(d); g1(i); g1(d); } #pragma instantiate void f1(int) // error - specific definition #pragma instantiate void g1(int) // error - no body provided
f1(double)
und g1(double)
werden wegen der fehlenden Template-Definitionen ebenfalls nicht instanziiert, jedoch in diesem Fall ohne die Ausgabe einer Fehlermeldung während der Übersetzung. Zum Bindezeitpunkt führen fehlende Template-Definitionen zu Binder-Fehlern.
Wenn als Pragma-Argument der Name einer Elementfunktion (z.B. A<int>::f
) angegeben wird, darf es sich um keine überladene Funktion handeln. Bei überladenen Elementfunktionen muss die vollständige Funktions-Deklaration angegeben werden, z.B. #pragma instantiate char * A<int>::f(int, char *)
Als Argumente der Instanziierungs-Pragmas sind Compiler-generierte Funktionen und reine virtuelle Funktionen generell unzulässig.
Wenn eine extern-inline Funktion oder eine inline Variable explizit instanziiert wird, wird dieses Symbol dem Modul der Instanziierung zugeordnet. Der externe Entry wird dann in diesem Modul angelegt.