With C++, is is quite easy to detect array on the stack using templates.... But type information must not be lost before being used. If you only want to support arrays, then you can delete the first function that works on pointers (or add a size parameter).
Alternatively, you can uses
instead (and have appropriate overload).
void Fun (int *p)
template <int N> void Fun(int (&p)[N])
int *p = a;
Generally if the code is complexe, then the template version should call a non-template version with an extra argument to avoid code-bloat and keep the convenience of not having to explicitly specify the size at the caller.
By the way first function should generally be deleted (or an extra size argument added) to avoid silent misuse.