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.
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)
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
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).