This isn't directly related to your problem, but there's a trick you can use with template parameter deduction to simplify the use of your function a bit:
Code:

template <typename T>
T max5(T,int);

can change to
Code:

// change the function prototype
template <typename T, int n>
T max5(T (&)[n] );

and the function definition changes accordingly
Code:

template <typename T>
T max5(T arr[],int n)
{
T max = 0;
for (int i=0; i<n; i++)
if arr[i]>max
max = arr[i];
return max;
}

to
Code:

template <typename T, int n>
T max5(T (&arr)[n] )
{
T max = 0;
for (int i=0; i<n; i++)
if (arr[i]>max)
max = arr[i];
return max;
}

Then change your call from
Code:

int max = max5(numbers, 5);

to
Code:

int max = max5(numbers);

in short, you can "deduce" the size of a statically sized array without needing to do any work. The prototype might look slightly more cryptic, but should make actual use of the function a bit easier