It's not necessary, but is recommended. Basically, every time you instantiate a template (declare an object with a different template parameter than before) the compiler has to know how to instantiate all its members. For instance, let's say you have this template in a .h:
template <class T> class MyTemplate
{
public:
void aMethod();
};
In x.cpp you define the method:
template <class T> void MyTemplate<T>::aMethod()
{
}
And after that you do:
void something()
{
MyTemplate<int> foo;
foo.aMethod();
}
This will compile and link, without errors. And, if you instantiate MyTemplate with <int>
in another,say, y.cpp module, it will also compile and link. BUT if in a third z.cpp module you instantiate MyTemplate with <double>
, this will compile but won't link, because aMethod for MyTemplate<double>
will be missing. The code for aMethod is in x.cpp; when the compiler compiles x.cpp, it doesn't know a <double>
instance should be generated. When it compiles z.cpp, it doesn't have the source code for the method.
With careful management of template instantiation, you could avoid completely the need to put the code in .h files. You just have to be sure that at least one module that uses a different template instance has the source code to generate the instance methods. But is it worth the trouble? In general, not.