Using Templates with g++

When using templated classes in a large, multi-file program you'll need to explicitly instantiate templated classes when using the g++ compiler. There are other options using #pragma (that I haven't tried), but the method outlined here is straightforward and works with all compilers (according to the C++ standard, your mileage may vary).

Normally you use the pre-processor to #include appropriate header files. For example, these import class declarations. You then normally link in the corresponding class definition which is traditionally in a matching .cc file (or .cpp, .cxx, etc.).

However, when a templated class is used, the implementation cannot be a priori compiled since a different implementation is needed for each instantiated template, e.g., Vector<int> and Vector<double> each require a (slightly) different implementation generated by the templated class definition. An easy solution to this is to #include the source code/implementation/definition of the templated class. This will work fine unless you do this and instantiate a Vector<int> in two separate files which are then linked --- the linker will complain about multiple definitions of the same functions. (Intelligent linkers might be the answer here, but as of yet ...).

The Template Instantiation File

To avoid the multiple definition problem, the implementation/definitions are #included in a separate, per program template instantation file. My convention is to use the name templatefoo.cc for a project whose executable is named foo. Here's an example of a template instantiation file for a word counting program (source is accessible from class home page.) #include "CPstring.h" #include "uvmap.h" #include "uvmap.cc" #include "uviterator.h" #include "uviterator.cc" // instantiate base classes template class Pair<string,int>; template class Map<string,int>; // instantiate unsorted vector implementation classes template class UVMapIterator<Pair<string,int> >; template class UVMap<string,int>; // instantiate hash table implementation classes #include "hmap.h" #include "hmap.cc" #include "hiterator.h" #include "hiterator.cc" template class HMap<string,int>; template class HMapIterator<string,int>;

The key here is the separate instantation of each templated class using the syntax:

template class ClassName<instantiating class>;

Alternatives

It's possible to put all the code in the class declaration, in essence making all member functions inline. Inline functions don't cause conflicts with multiple definitions when linking. This is the solution used in the Vector class since this class is used by beginning students who shouldn't be burdened with the separate instantation file. On some systems the compiler will generate warnings that the member functions aren't actually inlined (some of them are large). When g++ is used this isn't a problem since the warnings aren't generated when using plain compiler flags (e.g., -g).