Template class implementations

Hi there,

I'm currently writing small template classes
whereby (after hours of useless debugging)
I found out that template member functions
of the each respective template class have to be defined
in the same (header) file they were originally declared in.
Of course this is a valid solution that works, yet
there must be a smarter way to do that, for I don't want
300+ loc of pure implementation in a header file.
I read about people putting implementations into a
.cpp-file which they include at the end of their header file.
However this does not really work (for me) since it requires
an inclusion of the header file into the .cpp-file which consquently
re-includes the header file content into the header file itself.
So, where am I wrong or how am I to do better?
..I'm working with Visual Studio 2008 SP1
Thanks
there must be a smarter way to do that
Nope.
Templates are not classes. They are a "mold" by which the compiler will generate a class. Therefore the bodies of template functions are not visible during the linker process, because they don't actually exist -- they only exist if the template was instantiated. This is why you get the linker errors.

Anyway there are two solutions:

1) put the implementation in every cpp file that uses the template (this is what you said you didn't want to do)

2) instantiate classes from the template to make them externally linkable. The source file in which you instantiate the class must have the template implementation #included.

Example:

1
2
3
4
5
6
// foo.h
template <typename T> class Foo
{
public:
    void func();
};

1
2
3
4
5
6
7
// foo.cpp
#include "foo.h"

template <typename T> void Foo<T>::func()
{
  // do stuff
}


If you want to use this class with T=int, you must instantiate it:

1
2
3
4
// whatever cpp file that instantiates these classes
#include "foo.cpp"  // note .cpp, not .h

template class Foo<int>;  // instantiate the class 


Now, Foo<int> can be used anywhere in the program without having to #include the entire implementation, because it has been instantiated. Other types (such as Foo<double>) would still produce linker errors.


Whether or not this is "smarter" is up to you. I find this way more roundabout and I typically just end up #including the entire implementation in every source file that uses the template.
Last edited on
I typically just end up #including the entire implementation in every source file that uses the template


That seems indeed most natural, so think I'm going to stick to that. Maybe future language standard updates will come up with a slightly more convenient practice...
But thanks :)
If you are concerned about code bloat (you mentioned 300 loc)... there may be ways to reduce it, depending on what you're doing, by splitting the class into a non-templated base class containing most of the implementation and a thin template wrapper that derives from it.

jsmtih or anyone could i get some help with my program you all seem very well informed on c++ if you have email i would appreciate any help pkrawkstar718@aim.com ASAP plzzz thanks loads.
I think you are making a problem or finding a problem where there isn't a problem.
@pkrawkstar718

PM me (you'll need to enable PMs on your end) your code and we can work from there.
Topic archived. No new replies allowed.