I have a “childhood trauma”, I don’t really like templates - I think it’s better to use them in exceptional cases. There are not many cases where classes/methods must be templated.
I use my own indicator: if the template parameters are theoretically unknown in advance, then it is needed (for example, if this is a container type like std::vector<T>
).
If all parameters are known (for example void make_sound<TAnimalCat/TAnimalDog/TAnimalBird>()
), then it is better to make a virtual class IAnimal
.
But we often have to work with an established architecture, so let’s imagine that we have templates for a finite number of parameters.
The template code itself doesn’t do anything yet. Only when a method/class with some template parameters is called, the template is “instantiated”, that is, a new method/class is generated for these parameters.
When compiling each .cpp
file (a project may have hundreds of them), we often have to compile the same piece of code: example on godbolt.
Instantiated template functions have the linkonce_odr linkage type, you may want read my article about linkage types.
To avoid compiling the same code in each .cpp
file, you can “declare instantiations” for all known parameters using extern template
: example on godbolt.
In this case, somewhere else you need to “define instantiations” - for the example above, you need to write this in some .cpp
file:
1
2
template int calc<float>();
template int calc<double>();
Now the code in the template will be compiled only once (one time for each instantiation).
However, you can also keep all the template code in your .cpp
file, this often simplifies readability: example on godbolt.
You can evaluate the usefulness of different approaches:
- The
extern template
approach is not a full solution, because usually the gain in compilation speed is absolutely insignificant. - The approach with the template code completely in its
.cpp
file is not bad, it improves the readability of the code.