Image

Imageruakh wrote in Imagecpp

Template classes across multiple source files.

Okay, this is a rather clueless question, but please bear with me.

I generally make much use of header files. Generally, I'll have one source file, and it will include several header files that define all the classes I've made for the project, including all their data members and member functions.

Recently, someone convinced me that this is bad practice. He said that I should define my member functions - and any other functions, for that matter - in a separate file. Specifically, that I should define them in a source file, rather than a header file. (His reasoning was that if I included my header file in multiple source files, and my functions were defined in this header file, then a copy of my functions would get compiled into multiple object files, so when I built from the object files and tried to reference my functions, I would get a linker error to the tune of "multiply defined function" or whatnot.)

This is all well and good, but then when I have a class template, the .cpp that contains my function definitions isn't really compiled (since the compiler doesn't know what template classes will actually be used; recall that it's the compiler's job to take care of class templates, which it does by compiling a different version for each template class that is actually used). When I build from the object files, then, I get a linker error complaining that I never defined the particular version of the function that now needs to be used.

To put this less abstractly, I'll give some basic code demonstrating the problem. (This code actually uses a function template, rather than a class template, in the hopes of giving slightly simpler sample code.)

foo.h is just one line, reading thus:
template <typename TYPENAME> int FUNCTIONNAME();

foo.cpp is also just one line, reading thus:
template <typename TYPENAME> int FUNCTIONNAME() { return 0; }

main.cpp is two lines; one including foo.h, and one reading thus:
int main() { return FUNCTIONNAME<int>(); }

Compiling (using g++ -c main.cpp foo.cpp) works perfectly - no errors or warnings.

Linking (using g++ main.o foo.o -o main.exe) gives exactly one error, in main.o:
undefined reference to `int FUNCTIONNAME<int>()'

If I use MSVC++6, the results are similar, except that the error has the following text:
unresolved external symbol "int __cdecl FUNCTIONNAME(void)" (?FUNCTIONNAME@@YAHXZ)

Does anyone have any thoughts how to deal with this? I'm sure this is a problem others have encountered - after all, the STL is composed almost entirely of class templates (hence the 'T'); how have they dealt with it?

Thank you for any help. :-)