The second part of your question first: No, templates are compiled; not preprocessed.
Regarding the first part, they are incredibly useful. The best (and simplest) example of an expression parameter that lends itself with great functionality in templates is size limitations on a static arrays:
#include <iostream>
using namespace std;
template<typename T, size_t N>
void DoSomething(const T (&ar)[N])
{
for (size_t i=0; i<N; ++i)
cout << ar[i] << endl;
}
int main(int argc, char *argv[])
{
int int_ar[] = { 1,2,3,4,5 };
DoSomething(int_ar);
char char_ar[] = {'a', 'b', 'c'};
DoSomething(char_ar);
std::string str_ar[] = {"This", "is", "a", "string", "array."};
DoSomething(str_ar);
return EXIT_SUCCESS;
}
Output
1
2
3
4
5
a
b
c
This
is
a
string
array.
Such things are not possible without expression parameters. They are incredibly useful, especially for things that require size-deduction.