C++数组传入int*类型函数报错:无法获取数组长度
兄弟,这个报错的核心原因其实是C++里数组传参时的「退化(decay)」机制,咱们拆开了说就明白了:
先看能正常运行的代码
在GetArraySize.cpp的main函数里,myArray是实打实的固定大小数组类型(具体是int[7])。编译器在编译期就知道它的长度,所以std::begin(myArray)能直接拿到指向第一个元素的指针,std::end(myArray)能拿到指向数组最后一个元素后面的「尾后指针」,两者相减自然能得到数组的元素个数7。
再看报错的代码问题出在哪
当你把myArray传给getArraySize函数时,函数参数里的int intArray[]其实是个语法糖——编译器会自动把它转换成int* intArray。说白了,你传递给函数的根本不是数组本身,而是指向数组第一个元素的指针!
这时候你给std::end和std::begin传一个int*,它们就抓瞎了:指针没有内置的大小信息,std::end需要知道数组的具体长度才能找到尾后位置,自然就会抛出「找不到匹配的重载函数」的错误。
这个退化机制是C++从C继承来的,目的是避免拷贝整个大数组(毕竟数组可能很大),但代价就是一旦数组被作为参数传递,就彻底丢失了它的大小信息,只剩下一个光秃秃的指针。
怎么在不依赖C++17的前提下解决这个问题?
既然你想深入理解旧式数组的传参机制,那最贴合需求的解法是用模板+数组引用来避免退化:
修改你的函数为模板函数:
template <size_t N> int getArraySize(int (&intArray)[N]) { auto arraySize = std::end(intArray) - std::begin(intArray); return static_cast<int>(arraySize); }
原理是什么?
这里用了数组的引用作为参数,并且用模板参数N来捕获数组的大小。因为引用不会触发数组退化,所以intArray在这里仍然是int[N]类型——编译器能明确知道它的长度,std::begin和std::end就能正常工作了。调用的时候你还是像之前一样写getArraySize(myArray),编译器会自动根据传入的数组大小推导N的值。
如果不用模板,那你只能手动把数组大小作为参数传递给函数(比如getArraySize(myArray, 7)),但这显然不是你想要的——咱们要的是让函数自己能感知数组大小,而不是靠调用者传。
核心知识点总结
- 在数组定义的作用域内,数组是「固定大小数组类型」,能被
std::begin/std::end识别。 - 数组作为函数参数传递时,会自动退化为指向第一个元素的指针,丢失大小信息。
- 使用模板+数组引用的方式,可以绕过退化机制,保留数组的大小信息,让函数正确获取长度。
内容的提问来源于stack exchange,提问作者cdahms

