Im automatischen Instanziierungsmodus können Instanzen für Template-Einheiten (Funktions-Templates, Elementfunktionen und statische Datenelemente von Klassen-Templates) nur generiert werden, wenn das Objekt folgende Bedingungen erfüllt:
es ist nicht Bestandteil einer
.a-Bibliothekes enthält eine Referenz auf die Template-Einheit oder das Pragma
can_instantiatefür diese Template-Einheitund es enthält alle für die Instanziierung notwendigen Definitionen.
Eine Bibliothek, die zu ihrer Implementierung Instanzen benötigt, muss entweder diese Instanzen enthalten oder spezielle Include-Dateien mit can_instantiate-Pragmas bereitstellen. Diese beiden Möglichkeiten werden im Folgenden erläutert.
Die Bibliothek enthält alle benötigten Instanzen
Hierbei ist darauf zu achten, dass bei Verwendung mehrerer Bibliotheken keine Duplikate entstehen.
Um Template-Einheiten in Bibliotheken zu instanziieren, haben Sie folgende Möglichkeiten:
Automatische Instanziierung der Template-Einheiten durch den Prälinker mithilfe der Option
-y(siehe "Optionen zur Auswahl von Übersetzungsphasen").Achtung
Es besteht die Gefahr, dass bei der Verwendung mehrerer Bibliotheken, die die gleiche Instanz benötigen, Duplikate auftreten, da nicht pro Instanz ein separates Objekt erzeugt wird. Hier kann die Verwendung der Option
-T add_prelink_filesAbhilfe schaffen (siehe "Template-Optionen").Explizite Instanziierung aller Template-Einheiten mit der Instanziierungsanweisung
templatedeclaration oder mit dem Pragmainstantiate.Hierbei sollte darauf geachtet werden, dass pro Instanz ein separates Objekt erzeugt wird.
Beispiel
Es seien gegeben:
eine Bibliothek
l.amit Referenzen auf die Instanzent_list(Foo1)undt_list(Foo2),eine Include-Datei
listFoo.hmit den Deklarationen vont_list,Foo1undFoo2und eine Quelldatei
listFoo.Cmit den Definitionen vont_list,Foo1undFoo2.
// l.h #ifndef L_H #define L_H #include "listFoo.h" void g(); #endif // l.C (l.o ist ein Element von l.a) #include "l.h" void g() { Foo1 f1; Foo2 f2; //... t_list(f1); t_list(f2); //... } //listFoo.h #ifndef LIST_FOO_H #define LIST_FOO_H template <class T> void t_list (T t); class Foo1 {...}; class Foo2 {...}; #endif //listFoo.C template <class T> class t_list (T t) { ... };In der Bibliothek
l.asind die referenzierten Instanzen jeweils in separaten Objekten enthalten.// lf1.C : lf1.o ist ein Element von l.a // und enthält eine explizite Instanziierung von t_list(Foo1) #include "listFoo.h" template void t_list(Foo1); // lf2.C : lf2.o ist ein Element von l.a // und enthält eine explizite Instanziierung von t_list(Foo2) #include "listFoo.h" #pragma instantiate void t_list(Foo2)
Die Include-Dateien enthalten
can_instantiate-Pragmas für alle benötigten Instanzen.Beispiel
Es seien gegeben:
eine Bibliothek
l.amit einer Referenz auf die Instanzt_list(Foo)eine Include-Datei
listFoo.hmit den Deklarationen vont_listundFoound eine Quelldatei
listFoo.Cmit den Definitionen vont_listundFoo
// l.h #ifndef L_H #define L_H #include "listFoo.h" void g(); #endif // l.C (l.o ist ein Element von l.a) #include "l.h" void g() { Foo f; //... t_list(f); //... } //listFoo.h #ifndef LIST_FOO_H #define LIST_FOO_H template <class T> void t_list (T t); class Foo {...}; #pragma can_instantiate t_list(Foo) #endif //listFoo.C template <class T> void t_list (T t) {...};Das Objekt
user.ound die Bibliothekl.awerden zusammengebunden(CC user.o l.a).// user.C #include "l.h" int f () { g(); }user.Cinkludiertl.hundl.hinkludiert wiederumlistFoo.h. Somit enthältuser.Cden Hinweis, dasst_list(Foo)instanziiert werden kann.Bei der automatischen Instanziierung durch den Prälinker wird nur eine Instanz
t_list(Foo)generiert.Hinweis
Damit die benötigten Instanzen generiert werden können, muss das Pragmacan_instantiatein einer Include-Datei der Bibliothek enthalten sein, die dann jeweils von den Benutzerprogrammen inkludiert wird.