[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