[LC++]template and gcc

Chris Vine chris at cvine.freeserve.co.uk
Mon Mar 25 06:34:07 UTC 2002


On Sunday 24 March 2002 9:51 pm, Peter Poulsen wrote:
> I have this little program
>
> main.cpp:
> #include "run.h"
>
> void main()
> {
> 	run<int> r;
> 	r.running();
> }
>
> run.h:
> #include <iostream>
>
> template< typename T >
> class run
> {
> public:
> 	void running();
> };
>
>
> run.cpp:
> #include "run.h"
>
> template< typename T >
> void run<T>::running()
> {
> 	cout << "Running" << endl;
> }
>
> I compile it with the following command: g++ main.cpp run.cpp -o main
>
> I get the following message:
> /tmp/ccL9ZUDh.o: In function `main':
> /tmp/ccL9ZUDh.o(.text+0xe): undefined reference to
> `run<int>::running(void)' collect2: ld returned 1 exit status
>
> I'm using gcc version 2.96
>
> Can anybody see whats wrong? (note: if I write running in the header
> file as an inline method, it all works smothly)

You have a linker error, because the run template cannot be instantiated in 
main.cpp without seeing the definition of the template, which is in run.cpp.  
Adding run.cpp to the list of files to be compiled in the command line as you 
have done does not do anything, because no object code can be compiled from 
it in that way (the compiler is not psychic when trying to compile run.cpp, 
and cannot guess which types you are trying to compile the run template class 
for).

If in main.cpp you #include run.cpp instead of run.h it will work, or (as you 
discovered) if you include the whole template definition in run.h, or if you 
force an instantiation of the run<int> type in a translation unit that can 
see run.cpp and which the linker can link with, such as by ending run.cpp 
with something like:

class Dummy: public run<int> {} dummy;

The first two methods are better (the second is the one which template 
writers normally use), but can lead to multiple instantiations if the same 
type is instantiated in more than one translation unit and your linker is not 
sufficiently clued up - the program will run fine, but it may contain more 
than one instantiation of the same code and thus waste a little memory.

(There are other compiler specific ways of getting templates instantiated for 
particular types, but they are non-portable).  There is also now an "export" 
keyword which under the C++ standard will do what you want, but I do not know 
of any compilers which have yet implemented it.

Incidentally, the prototype of main() is int main(), not void main().

Chris.




More information about the tuxCPProgramming mailing list