非类型模板形参-数组解决思路

非类型模板形参---数组
哇 我被吓到了.......一个参数居然能同时传递数组地址和数组长度...............

template <class T, int N> void array_init(T (&parm)[N])
{
cout<<N<<endl;
}
 
int main()
{
int x[4];
array_init(x);

system("pause>NUL");
    return 0;


问题一:怎么能这样啊,我只传递了x啊,为什么N就是4了!这个让太让我震惊了!感觉像是java之类的语言.........一般数组做参数不都是需要两个参数吗?一个传数组地址,另一个传数组长度........

问题二:如果我把函数的形参写成: T parm[N]  就报错了   为什么?为什么这里必须是引用???


跪求解惑啊   确实震惊到了...

谢谢!
------解决方案--------------------
引用:
为什么传引用就能确定N?或者说,为什么引用会携带上数组长度?这是什么机制?

这是因为具有某个类型的某个长度的数组也被当成一个独立的类型。只要不是void的类型都可以有对应的引用。
另外要强调的是数组名不是指针,在值方式传参数时丢失长度靠的是隐式转换(而不是原本就忽略长度了)。这个问题在论坛里看到有多起争议,而数组的引用就是证明这一说法最好的例子。
------解决方案--------------------

#include <conio.h>

template < typename T1, typename T2, typename T3, size_t N1, char N2 >
class CMatcher
{
};

template < typename T1, typename T2, typename T3, size_t N1, char N2 >
void fTest(CMatcher<T1, T2, T3, N1, N2>)
{
std::cout << typeid(T1).name() << ", " << typeid(T2).name() << ", " << typeid(T3).name()
<< "; " << N1 << ", " << N2 << std::endl;
}

int main(void)
{
CMatcher<char, int, float, 1, '2'> o1;
CMatcher<long, unsigned int, void, 3, '4'> o2;

fTest(o1);
fTest(o2);
_getch();
return 0;
}


输出结果:

char, int, float; 1, 2
long, unsigned int, void; 3, 4