Your Browser is not longer supported

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

{{viewport.spaceProperty.prod}}

Bibliotheken und Templates

&pagelevel(4)&pagelevel

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-Bibliothek

  • es enthält eine Referenz auf die Template-Einheit oder das Pragma can_instantiate für diese Template-Einheit

  • und 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.

  1. 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:

    1. 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_files Abhilfe schaffen (siehe "Template-Optionen").

    2. Explizite Instanziierung aller Template-Einheiten mit der Instanziierungsanweisung template declaration oder mit dem Pragma instantiate.

      Hierbei sollte darauf geachtet werden, dass pro Instanz ein separates Objekt erzeugt wird.

      Beispiel

      Es seien gegeben:

      • eine Bibliothek l.a mit Referenzen auf die Instanzen t_list(Foo1) und t_list(Foo2),

      • eine Include-Datei listFoo.h mit den Deklarationen von t_list, Foo1 und Foo2

      • und eine Quelldatei listFoo.C mit den Definitionen von t_list, Foo1 und Foo2.

      // 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.a sind 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)
      
  2. Die Include-Dateien enthalten can_instantiate-Pragmas für alle benötigten Instanzen.

    Beispiel

    Es seien gegeben:

    • eine Bibliothek l.a mit einer Referenz auf die Instanz t_list(Foo)

    • eine Include-Datei listFoo.h mit den Deklarationen von t_list und Foo

    • und eine Quelldatei listFoo.C mit den Definitionen von t_list und Foo

    // 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.o und die Bibliothek l.a werden zusammengebunden(CC user.o l.a).

    // user.C
    #include "l.h"
    int f ()
    {
       g();
    }
    

    user.C inkludiert l.h und l.h inkludiert wiederum listFoo.h. Somit enthält user.C den Hinweis, dass t_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 Pragma can_instantiate in einer Include-Datei der Bibliothek enthalten sein, die dann jeweils von den Benutzerprogrammen inkludiert wird.