Code:

#include <iostream>
template <typename T> class flag1{flag1();};
template <typename T> class flag2{flag2();};
template <typename T> class flag3{flag3();};
template <typename T1> void f1(int, const T1[]){std::cout << "f1-1\n";}
template <typename T1> void f1(int, const T1&){std::cout << "f1-2\n";}
template <typename T1, unsigned N> void f1(int, const T1(&)[N]){std::cout << "f1-3\n";}
template <typename T1> void f2(int, const T1[]){std::cout << "f2-1\n";}
template <typename T1> void f2(int, const T1&){std::cout << "f2-2\n";}
template <typename T1, unsigned N> void f2(int, const T1(&)[N]){std::cout << "f2-3\n";}
template <typename T1> void f3(int, const T1[], int) {std::cout << "f3-1\n";}
template <typename T1> void f3(int, const T1&, int){std::cout << "f3-2\n";}
template <typename T1, unsigned N> void f3(int, const T1(&)[N], int){std::cout << "f3-3\n";}
template <typename T1> void f4(int, const T1[], int) {std::cout << "f4-1\n";}
template <typename T1> void f4(int, const T1&, int){std::cout << "f4-2\n";}
template <typename T1, unsigned N> void f4(int, const T1(&)[N], int){std::cout << "f4-3\n";}
template <typename T1, typename T2> void f5(int, const T1[], const T2&){std::cout << "f5-1\n";}
template <typename T1, typename T2> void f5(int, const T1&, const T2&){std::cout << "f5-2\n";}
template <typename T1, typename T2, unsigned N> void f5(int, const T1(&)[N], const T2&){std::cout << "f5-3\n";}
template <typename T1, typename T2> void f6(int, const T1[], const T2&){std::cout << "f6-1\n";}
template <typename T1, typename T2> void f6(int, const T1&, const T2&){std::cout << "f6-2\n";}
template <typename T1, typename T2, unsigned N> void f6(int, const T1(&)[N], const T2&){std::cout << "f6-3\n";}
int main()
{
double a[10];
double * b = new double[10];
f1(1, a);
f1(1, &a[0]);
f1(1, b);
f1(1, &b[0]);
std::cout << '\n';
f2(1, a);
f2(1, &a[0]);
f2(1, b);
f2(1, &b[0]);
std::cout << '\n';
f3(1, a, 10);
f3(1, &a[0], 10);
f3(1, b, 10);
f3(1, &b[0], 10);
std::cout << '\n';
f4(1, a, 10);
f4(1, &a[0], 10);
f4(1, b, 10);
f4(1, &b[0], 10);
std::cout << '\n';
f5(1, a, 10);
f5(1, &a[0], 10);
f5(1, b, 10);
f5(1, &b[0], 10);
std::cout << '\n';
f6(1, a, 10);
f6(1, &a[0], 10);
f6(1, b, 10);
f6(1, &b[0], 10);
std::cout << '\n';
return(0);
}