范围for循环要求对象支持begin()和end(),以便获取迭代器进行遍历,适用于数组、标准容器等可迭代类型。

在C++11中,范围for循环(range-based for loop)只能用于“可迭代”的对象,也就是说,该对象必须支持
begin()和
end())函数。我们来分别看原始指针和数组的情况。
1. 范围for循环与普通数组
对于具有已知大小的普通数组(即在作用域内定义的数组),范围for循环是可以使用的。
示例:
int arr[] = {1, 2, 3, 4, 5};
for (int x : arr) {
std::cout << x << " ";
}
这段代码是合法的。因为在数组的上下文中,编译器知道
arr的类型是
int[5],可以推导出
begin(arr)和
end(arr),从而支持范围for。
2. 范围for循环与原始指针
如果变量只是一个原始指针(例如通过
new分配或传入函数的指针),则不能直接使用范围for循环,因为指针不携带大小信息,也无法推导出
begin和
end。
立即学习“C++免费学习笔记(深入)”;
错误示例:
int* ptr = new int[5]{1, 2, 3, 4, 5};
for (int x : ptr) { // 编译错误!ptr是指针,不是数组
std::cout << x << " ";
}
这会引发编译错误,因为
ptr的类型是
int*,而
std::begin(ptr)无法确定数组边界。
3. 在函数参数中传递数组退化为指针
即使你定义了一个数组并传入函数,如果参数是按指针接收的,也会失去数组大小信息。
示例:
void func(int arr[]) { // 实际上等价于 int* arr
for (int x : arr) { // 编译错误!arr退化为指针
// ...
}
}
这种情况下,
arr已经是指针,不能再用于范围for循环。
4. 如何安全使用范围for
推荐使用标准容器或
std::array,它们天然支持范围for循环。 推荐方式:
std::arrayarr = {1, 2, 3, 4, 5}; for (int x : arr) { std::cout << x << " "; }
或者使用
std::vector:
std::vectorvec = {1, 2, 3, 4, 5}; for (int x : vec) { std::cout << x << " "; }
基本上就这些。范围for循环对普通数组有效,但对原始指针无效,因为缺少迭代所需的边界信息。使用现代C++容器能避免这类问题。










