Range-based
for
loop
(since C++11)
在某个范围内执行 for 循环。
作为传统 for 循环 的更可读替代方案,用于遍历一定范围内的值,例如容器中的所有元素。
目录语法
说明上述语法生成的代码等效于以下内容 除了 range-initializer 临时对象的生存期扩展(参见 下文 ) (C++23 起) (包裹在 /* */ 中的变量和表达式仅用于说明):
range-initializer 会被求值以初始化要迭代的序列或范围。该序列中的每个元素会依次被解引用,并用于初始化具有 item-declaration 中给定的类型和名称的变量。 item-declaration 可以是以下之一: 说明性表达式 /* begin-expr */ 与 /* end-expr */ 定义如下:
如果循环需要在 statement 内终止,可以使用 break 语句 作为终止语句。 若需要在 statement 中终止当前迭代,可使用 continue 语句 作为快捷方式。 如果在 init-statement 中引入的名称在 statement 的最外层块中被重新声明,则程序非良构: for (int i : {1, 2, 3}) int i = 1; // 错误:重复声明 临时范围初始化器如果 range-initializer 返回一个临时对象,其生命周期将延长至循环结束,这是通过绑定到转发引用 /* range */ 实现的。 所有位于 范围初始化器 内的临时对象生命周期均不会延长 ,除非它们原本就会在 范围初始化器 结束时被销毁 (C++23 起) 。 // 如果 foo() 通过值返回 for (auto& x : foo().items()) { /* ... */ } // C++23 之前是未定义行为
注释如果 range-initializer 是一个 大括号包围的初始化列表 , /* range */ 会被推导为 std::initializer_list 的引用。 在泛型代码中使用推导至转发引用是安全的,实际上更可取, for ( auto && var : sequence ) 。
当范围类型拥有名为“
虽然在 item-declaration 中声明的变量通常会在 statement 中使用,但并非必须如此。
当与具有写时复制语义的(非const)对象一起使用时,基于范围的
for
循环可能通过(隐式)调用非const
关键词示例
运行此代码
#include <iostream> #include <vector> int main() { std::vector<int> v = {0, 1, 2, 3, 4, 5}; for (const int& i : v) // 通过常量引用访问 std::cout << i << ' '; std::cout << '\n'; for (auto i : v) // 通过值访问,i的类型为int std::cout << i << ' '; std::cout << '\n'; for (auto&& i : v) // 通过转发引用访问,i的类型为int& std::cout << i << ' '; std::cout << '\n'; const auto& cv = v; for (auto&& i : cv) // 通过转发引用访问,i的类型为const int& std::cout << i << ' '; std::cout << '\n'; for (int n : {0, 1, 2, 3, 4, 5}) // 初始化器可以是 // 花括号包围的初始化列表 std::cout << n << ' '; std::cout << '\n'; int a[] = {0, 1, 2, 3, 4, 5}; for (int n : a) // 初始化器可以是数组 std::cout << n << ' '; std::cout << '\n'; for ([[maybe_unused]] int n : a) std::cout << 1 << ' '; // 循环变量不需要被使用 std::cout << '\n'; for (auto n = v.size(); auto i : v) // 初始化语句(C++20) std::cout << --n + i << ' '; std::cout << '\n'; for (typedef decltype(v)::value_type elem_t; elem_t i : v) // 类型定义声明作为初始化语句(C++20) std::cout << i << ' '; std::cout << '\n'; for (using elem_t = decltype(v)::value_type; elem_t i : v) // 别名声明作为初始化语句(C++23) std::cout << i << ' '; std::cout << '\n'; } 输出: 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 1 1 1 1 1 1 5 5 5 5 5 5 0 1 2 3 4 5 0 1 2 3 4 5 缺陷报告以下行为变更缺陷报告被追溯应用于先前发布的 C++ 标准。
另见
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||