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
.a
library,it contains a reference to the template entity or the
can_instantiate
pragma 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_files
option (see "Template options").by explicitly instantiating all template entities with the instantiation directive
template
declaration or theinstantiate
pragma.The main point to be observed here is to ensure that a separate object is created per entity.
Example
Given:
a library
l.a
with references to the instancest_list(Foo1)
andt_list(Foo2),
a header file
listFoo.h
with the declarations oft_list
,Foo1
andFoo2
and a source file
listFoo.C
with the definitions oft_list
,Foo1
andFoo2
// 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_instantiate
pragmas for all required instances.Example
Given:
a library
l.a
with a reference to the instancet_list(Foo)
,a header file
listFoo.h
with the declarations oft_list
andFoo
and a source file
listFoo.C
with the definitions oft_list
andFoo
.
// 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.o
and the libraryl.a
are linked together (CC user.o l.a
).// user.C #include "l.h" int f () { g(); }
user.C
includesl.h
, which in turn includeslistFoo.h
. Consequently,user.C
contains 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_instantiate
pragma must be contained in a header file of the library that will be included by the user programs.