I would say, both compiler-time code execution and preprocessor replacement are the abuse of templates.
They were introduced in C++ to make it possible to parametrize functions (methods, classes, enums, etc) by argument types not only by argument values.
As an immediate example, there are container classes, say
list. This class functionality allows constructing, structural modification, iteration etc operations that are essentially the same for any type of list elements. That is why a single template class is sufficient for them. Still, because C++ is statically typed language, you cannot define a list implementation without knowing the type of its elements. And this type is a parameter of container template, e.g.
list<int> is list of integers,
list<string> is list of strings etc.