Instantiations for template entities (template functions, member functions and static data members of template classes) can be generated in automatic instantiation mode only if the object meets the following conditions:
It is not part of a
.alibrary,it contains a reference to the template entity or the
can_instantiatepragma for that template entity,and it contains all definitions needed for the instantiation.
A library that requires instances for its implementation must either contain these instances or provide special headers with can_instantiate pragmas. These two options are explained individually below.
The library contains all required instances
The main point to be observed here is to ensure that no duplicates are created when using multiple libraries.
The instantiation of template entities in libraries can be achieved by the following methods:
automatic instantiation of the template unit using the prelinker with the option
-y(see "Options for selecting compilation phases").Caution
If multiple libraries that require the same entity are used, there is a potential risk of duplicates being created, since a separate object is not created per entity. This can be avoided by using the
-T add_prelink_filesoption (see "Template options").by explicitly instantiating all template entities with the instantiation directive
templatedeclaration or theinstantiatepragma.The main point to be observed here is to ensure that a separate object is created per entity.
Example
Given:
a library
l.awith references to the instancest_list(Foo1)andt_list(Foo2),a header file
listFoo.hwith the declarations oft_list,Foo1andFoo2and a source file
listFoo.Cwith the definitions oft_list,Foo1andFoo2
// l.h #ifndef L_H #define L_H #include "listFoo.h" void g(); #endif // l.C (l.o is an element of 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) { ... };Each of the referenced instances are contained in separate objects in the library l.a.
// lf1.C (lf1.o is an element of l.a) // and contains an explicit instantiation for t_list(Foo1) #include "listFoo.h" template void t_list(Foo1); // lf2.C (lf2.o is element of l.a) // and contains an explicit instantiation for t_list(Foo2) #include "listFoo.h" #pragma instantiate void t_list(Foo2)
The header files contain
can_instantiatepragmas for all required instances.Example
Given:
a library
l.awith a reference to the instancet_list(Foo),a header file
listFoo.hwith the declarations oft_listandFooand a source file
listFoo.Cwith the definitions oft_listandFoo.
// l.h #ifndef L_H #define L_H #include "listFoo.h" void g(); #endif // l.C (l.o is an element of 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) {...};The object
user.oand the libraryl.aare linked together (CC user.o l.a).// user.C #include "l.h" int f () { g(); }user.Cincludesl.h, which in turn includeslistFoo.h. Consequently,user.Ccontains notification thatlist(Foo)can be instantiated.Automatic instantiation by the prelinker produces only one instance
t_list(Foo).Note
In order to generate the needed instances, the
can_instantiatepragma must be contained in a header file of the library that will be included by the user programs.