More generally, compiling a template doesn't do much. Microsoft only recently abandoned something one could roughly call a text replacement implementation for templates:
The method chosen to implement this [templates, in the old compiler] was to do some minimal parsing of
a template and then capture the whole template as a string of tokens
(this is very similar to how macros are handled in the compiler). Later, when a template is instantiated, that token stream would be replayed through the parser and template arguments would be replaced.
The reason this was abandoned is that it is not quite sufficient to implement templates correctly. But a template in C++ is still very much a template in the semantic sense, which is why the the usual method to compile template using code involves having the template source available.
This is a striking contrast to C# which compiles standalone templates in the strict sense (to IL, of course).
Instantiating a template does more:
#include<iostream>
using namespace std;
// this works;
template<typename T> T f(T t)
{
return cout;
}
// this doesn't
// double d = f(1.0);