一、示例说明
//代码示例
//情景一:
int main() {
int array[] = {1,2,3,4};
std::cout << sizeof (array) / sizeof (*array) << std::endl;
return 0;
}
//情景二:
int test_func(int array[]) {
std::cout << sizeof (array) / sizeof (*array) << std::endl;
}
int main() {
int array[] = {1,2,3,4};
test_func(array);
return 0;
}
//情景三:
template <typename T>
void test_func(T&& array) {
std::cout << sizeof(array) / sizeof(*array) << std::endl;
}
int main() {
int array[] = {1,2,3,4};
test_func(array);
return 0;
}
实际输入结果如下:
//1
9
//2
2 //实际 sizeof(long) / sizeof(int)
//3
9
所以我们得出的结论是:
1 作用域内 sizeof 能够计算出数组的长度
2 胯作用域使用 传递地址方式传递 sizeof 能做的是将地址转化成长整形计算出 long 的长度
3 通过模板函数地址传递能够确保数组被完整的传递过去
二、问题解析
2.1 范例二说明
先看预编译输出内容
test.cpp:182:25: warning: sizeof on array function parameter will return size of ‘int *’ instead of ‘int []’
test.cpp:181:17: note: declared here
从编译输出来看,显然它认识到这玩意儿是个数组,但是它不太清楚你为啥只填了一个地址,所以它就猜你可能需要计算它地址长度,就是 int * 而不是 int[] (典型好心办坏事)
而一个地址一般都是 16 进制的长整形,所以这就是为何 sizeof(array) 计算出 8 (计算机内部地址总线的宽度)
2.2 范例三说明
核心在于 T&& array
根据模板推导原则,T array
它直接拿到的就是数组地址,而 && / & 就会自动推导来保留数组形态