首先要明确一点,数组类型和指针类型确实是不同的类型!

char *p; //类型是char*

char str[6];//类型是char [6]

可用如下语句输出类型信息(需要#include<typeinfo>)

std::cout << typeid(p).name() << std::endl;
std::cout << typeid(str).name() << std::endl;

但是有时候我们总会定义这样的函数:

void foo(char *p){

   cout << p << endl;

   cout << sizeof(p) / sizeof(char); // 输出为4

}

我们发现把str丢进去它也正常运行了。于是想当然的,我就定义了这样一个函数:

void foo(char str[6]){

   cout << str << endl;

   cout << sizeof(str) / sizeof(char) << endl;// 输出也是4

}

我们发现输入p也没问题,这就有问题了,而且第二个输出让人费解,按照类型信息它应该输出6。

这里涉及的问题,就是,当你以非引用类型作为形参的时候,数组类型会被自动降为指针类型来处理,也就是foo(char str[6])跟 foo(char *p)是完全一样的!

 

为了演示这个知识点,我们将函数原型改成下面这样:

void foo(char (&str)[6]){

   cout << str << endl;

   cout << sizeof(str) / sizeof(char) << endl;// 输出为6

}

这时候,我们发现只有输入char[6]类型,才能通过编译,而且第二个输出为6,也就是数组长度信息在传参过程中正常保留了。

当以引用类型为形参的时候,数组类型不会降为指针类型!

最后,基于这一点,我们可以写出以任意维数组为参数的函数了,当然要用到模板,因为不同长度的数组属于不同的类型:

template<int N, int M>
int foo(int const (&a)[N][M], int const (&b)[N][M]){
std::cout << typeid(a).name() << std::endl; //输出 int[N][M]
return 0;
}