为何C++ foreach循环遗漏&会报错?请解析原因
为什么二维数组范围for循环漏写&会报错?
这个问题我之前帮很多开发者理清楚过,核心要搞懂C++数组的「退化特性」和范围for循环的工作逻辑:
先看正确代码的逻辑
当你写for(auto &i : arr)时:
arr的类型是int[3][2],它的每个元素是**int[2]类型的一维数组**- 用
auto &i接收时,i是这个一维数组的引用(类型为int (&)[2]),完全保留了数组的类型信息(包括长度) - 内层的
for(int j : i)能正常工作,因为范围for循环可以通过数组类型直接获取它的起始和结束位置(编译期已知长度2)
错误代码的问题出在哪?
当你漏写&写成for(auto i : arr)时:
- C++里数组是不能直接被值拷贝的(你试试写
int a[2] = {1,2}; int b[2] = a;,编译器直接报错) - 所以编译器会把一维数组
int[2]隐式转换成指向数组第一个元素的指针(也就是int*),最终i的实际类型是int*,而不是你预期的“拷贝后的数组” - 接下来内层的
for(int j : i)就会触发错误:范围for循环需要遍历的对象必须能提供明确的范围(比如数组、容器,或支持begin()/end()的类型),但指针int*只是一个内存地址,编译器根本不知道它指向的内存有多少个元素,所以找不到匹配的std::end()函数——这就是你看到的报错信息(编译器找到了valarray的end()重载,但和指针类型不匹配)
关于你“深拷贝数组”的疑惑
C++原生数组不支持值拷贝语义,所以不存在“深拷贝数组对象”的情况。如果想要实现类似的功能,你可以用std::array容器,它是原生数组的封装,支持值拷贝:
#include <array> #include <iostream> int main() { std::array<std::array<int, 2>, 3> arr = {{{1,2}, {3,4}, {5,6}}}; for(auto i : arr) { // 这里不需要&也能正常工作,因为std::array支持值拷贝 for(int j : i) { std::cout << j << " "; } std::cout << std::endl; } return 0; }
内容的提问来源于stack exchange,提问作者Nikhil
相关产品推荐
相关产品推荐

