Что происходит, так это то, что компилятор создает функцию для каждого типа (конечно, используется один). Итак, у вас были бы следующие «функции» внутри:
int my_max (const int &t1, const int &t2)
{
static int counter = 0;
counter++;
cout << counter << " ";
return ((t1 > t2) ? t1 : t2);
}
...
double my_max (const double &t1, const double &t2)
{
static int counter = 0;
counter++;
cout << counter << " ";
return ((t1 > t2) ? t1 : t2);
}
...
char my_max (const char &t1, const char &t2)
{
static int counter = 0;
counter++;
cout << counter << " ";
return ((t1 > t2) ? t1 : t2);
}
Я думаю, понятно, что каждая функция независима. Они ничего не разделяют, за исключением того, что они генерируются одним и тем же кодом шаблона.