Go forward to C++ Signatures.
Go backward to C++ Interface.
Go up to C++ Extensions.

Where's the Template?
=====================

   C++ templates are the first language feature to require more
intelligence from the environment than one usually finds on a UNIX
system.  Somehow the compiler and linker have to make sure that each
template instance occurs exactly once in the executable if it is needed,
and not at all otherwise.  There are two basic approaches to this
problem, which I will refer to as the Borland model and the Cfront
model.

Borland model
     Borland C++ solved the template instantiation problem by adding
     the code equivalent of common blocks to their linker; template
     instances are emitted in each translation unit that uses them, and
     they are collapsed together at run time.  The advantage of this
     model is that the linker only has to consider the object files
     themselves; there is no external complexity to worry about.  This
     disadvantage is that compilation time is increased because the
     template code is being compiled repeatedly.  Code written for this
     model tends to include definitions of all member templates in the
     header file, since they must be seen to be compiled.

Cfront model
     The AT&T C++ translator, Cfront, solved the template instantiation
     problem by creating the notion of a template repository, an
     automatically maintained place where template instances are
     stored.  As individual object files are built, notes are placed in
     the repository to record where templates and potential type
     arguments were seen so that the subsequent instantiation step
     knows where to find them.  At link time, any needed instances are
     generated and linked in.  The advantages of this model are more
     optimal compilation speed and the ability to use the system
     linker; to implement the Borland model a compiler vendor also
     needs to replace the linker.  The disadvantages are vastly
     increased complexity, and thus potential for error; theoretically,
     this should be just as transparent, but in practice it has been
     very difficult to build multiple programs in one directory and one
     program in multiple directories using Cfront.  Code written for
     this model tends to separate definitions of non-inline member
     templates into a separate file, which is magically found by the
     link preprocessor when a template needs to be instantiated.

   Currently, g++ implements neither automatic model.  In the mean time,
you have three options for dealing with template instantiations:

  1. Do nothing.  Pretend g++ does implement automatic instantiation
     management.  Code written for the Borland model will work fine, but
     each translation unit will contain instances of each of the
     templates it uses.  In a large program, this can lead to an
     unacceptable amount of code duplication.

  2. Add `#pragma interface' to all files containing template
     definitions.  For each of these files, add `#pragma implementation
     "FILENAME"' to the top of some `.C' file which `#include's it.
     Then compile everything with -fexternal-templates.  The templates
     will then only be expanded in the translation unit which
     implements them (i.e. has a `#pragma implementation' line for the
     file where they live); all other files will use external
     references.  If you're lucky, everything should work properly.  If
     you get undefined symbol errors, you need to make sure that each
     template instance which is used in the program is used in the file
     which implements that template.  If you don't have any use for a
     particular instance in that file, you can just instantiate it
     explicitly, using the syntax from the latest C++ working paper:

          template class A<int>;
          template ostream& operator << (ostream&, const A<int>&);

     This strategy will work with code written for either model.  If
     you are using code written for the Cfront model, the file
     containing a class template and the file containing its member
     templates should be implemented in the same translation unit.

     A slight variation on this approach is to use the flag
     -falt-external-templates instead; this flag causes template
     instances to be emitted in the translation unit that implements
     the header where they are first instantiated, rather than the one
     which implements the file where the templates are defined.  This
     header must be the same in all translation units, or things are
     likely to break.

     See Declarations and Definitions in One Header: C++ Interface,
     for more discussion of these pragmas.

  3. Explicitly instantiate all the template instances you use, and
     compile with -fno-implicit-templates.  This is probably your best
     bet; it may require more knowledge of exactly which templates you
     are using, but it's less mysterious than the previous approach,
     and it doesn't require any `#pragma's or other g++-specific code.
     You can scatter the instantiations throughout your program, you
     can create one big file to do all the instantiations, or you can
     create tiny files like

          #include "Foo.h"
          #include "Foo.cc"
          
          template class Foo<int>;

     for each instance you need, and create a template instantiation
     library from those.  I'm partial to the last, but your mileage may
     vary.  If you are using Cfront-model code, you can probably get
     away with not using -fno-implicit-templates when compiling files
     that don't `#include' the member template definitions.