How does the compilation of templates work?

The compiler generates the code for the specific types given in the template class instantiation.

If you have for instance a template class declaration as

template<typename T>
class Foo
{
public:
     T& bar()
     {
         return subject; 
     }
private:
     T subject;
};

as soon you have for example the following instantiations

Foo<int> fooInt;
Foo<double> fooDouble;

these will effectively generate the same linkable code as you would have defined classes like

class FooInt
{
public:
     int& bar()
     {
         return subject; 
     }
private:
     int subject;
}

and

class FooDouble
{
public:
     double& bar()
     {
         return subject; 
     }
private:
     double subject;
}

and instantiate the variables like

FooInt fooInt;
FooDouble fooDouble;

Regarding the point that template definitions (don’t confuse with declarations regardless of templates) need to be seen with the header (included) files, it’s pretty clear why:
The compiler can’t generate this code without seeing the definition. It can refer to a matching instantiation that appeared first at linking stage though.

What does a non-template member function have that allows for it to
be defined outside of the header that a template function doesn’t
have?

The declaration of a non-template class/member/function gives a predefined entry point for the linker. The definition can be drawn from a single implementation seen in a compiled object file (== .cpp == compilation unit).
In contrast the declaration of a templated class/member/function might be instantiated from arbitrary compilation units given the same or varying template parameters. The definition for these template parameters need’s to be seen at least once. It can be either generic or specialized.

Note that you can specialize template implementations for particular types anyway (included with the header or at a specific compilation unit).
If you would provide a specialization for your template class in one of your compilation units, and don’t use your template class with types other than specialized, that also should suffice for linking it all together.

I hope this sample helps clarifying what’s the difference and efforts done from the compiler.

Leave a Comment