Go to the first, previous, next, last section, table of contents.

Problems with the template implementation

g++ does not implement a separate pass to instantiate template functions and classes at this point; for this reason, it will not work, for the most part, to declare your template functions in one file and define them in another. The compiler will need to see the entire definition of the function, and will generate a static copy of the function in each file in which it is used.

(The experimental template repository code (see See section How do I use the new repository code?) that can be added to 2.7.0 or later does implement a separate pass, but there is still no searching of files that the compiler never saw).

For version 2.6.0, however, a new switch -fno-implicit-templates was added; with this switch, templates are expanded only under user control. I recommend that all g++ users that use templates read the section "Template Instantiation" in the gcc manual (version 2.6.x and newer). g++ now supports explicit template expansion using the syntax from the latest C++ working paper:

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

As of version 2.6.3, there are still a few limitations in the template implementation besides the above (thanks to Jason Merrill for this info): These are still present in version 2.7.2, but a new implementation of templates planned for version 2.8 will eliminate them.

  1. Static data member templates are not supported. You can work around this by explicitly declaring the static variable for each template specialization:
    template <class T> struct A {
      static T t;
    };
    
    template <class T> T A<T>::t = 0; // gets bogus error
    int A<int>::t = 0;                // OK (workaround)
    
    (still a limitation in 2.7.2)
  2. Template member names are not available when defining member function templates.
    template <class T> struct A {
      typedef T foo;
      void f (foo);
      void g (foo arg) { ... }; // this works
    };
    
    template <class T> void A<T>::f (foo) { } // gets bogus error
    
  3. Templates are instantiated using the parser. This results in two problems: a) Class templates are instantiated in some situations where such instantiation should not occur.
    template <class T> class A { };
    A<int> *aip = 0; // should not instantiate A<int> (but does)
    
    b) Function templates cannot be inlined at the site of their instantiation.
    template <class T> inline T min (T a, T b) { return a < b ? a : b; }
    
    void f () {
      int i = min (1, 0);           // not inlined
    }
    
    void g () {
      int j = min (1, 0);           // inlined
    }
    
    A workaround that works in version 2.6.1 and later is to specify
    extern template int min (int, int);
    
    before f(); this will force it to be instantiated (though not emitted).
  4. Member function templates are always instantiated when their containing class is. This is wrong.

Go to the first, previous, next, last section, table of contents.