购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

1.8 使用基于range的for循环迭代range

许多编程语言都支持for循环的变体for each语法,即在集合的元素上重复执行一组语句。C++直到C++11才支持这一核心特性。最接近该特性的是标准库中的通用算法std::for_each,它将函数应用于范围(range)内的所有元素。C++11支持for each语法特点的术语被称为“基于range的for循环”。C++17标准中对其做了进一步的拓展。

1.8.1 准备工作

在C++11中,基于range的for循环遵循下面的语法:

为了举例说明基于range的for循环的各种方式,我们将使用以下函数,它们返回元素序列:

在下一小节中,我们可以学到各种基于range的for循环的使用方式。

1.8.2 使用方式

基于range的for循环的多种使用方式:

❍ 指定序列元素的特定类型:

❍ 不指定序列元素类型,让编译器自行推导:

❍ 通过在C++17中使用结构化绑定和分解声明:

1.8.3 工作原理

1.8.2节中显示的基于range的for循环的表达式基本上是语法糖,因为编译器将它转换成了其他东西。在C++17之前,编译器生成的代码通常像下面这样:

begin_expr和end_expr在这段代码中的值取决于range的类型:

❍ 对于类C数组:它们分别是__range和__range+__bound(其中__bound是数组中元素的数量)。

❍ 对于具有begin和end成员(无论其类型和可访问性如何)的类类型:它们分别是__range.begin()和__range.end()。

❍ 对于其他类型,则分别是begin(__range)和end(__range),可通过参数依赖查找确定。

值得注意的是,如果一个类包含任何名为begin或end的成员(函数、数据成员或枚举器),无论其类型和可访问性如何,begin_expr和end_expr都将选择它们。因此,在基于range的for循环中不能使用这种类类型。

在C++17中,编译器生成的代码略有不同:

新标准删除了begin表达式和end表达式必须是同一类型的约束。end表达式不需要是一个实际的迭代器,但它必须能够与迭代器进行比较,这样做的一个好处是可以用谓词来分隔range。另外,end表达式只求值一次,而不是每次迭代循环时都求值,这将会提高性能。

1.8.4 延伸阅读

❍ 阅读1.9节,以了解如何能将用户自定义类型与基于range的for循环一起使用。

❍ 阅读12.5节,以学习C++20 range库的基础知识。

❍ 阅读12.6节,以了解如何使用用户自定义的range适配器扩展C++20 range库的功能。 d09m15j27RAXPJLmdM18CiMC75mk6G57qEjhoeJu451/KKiBM6KB7GNy9fRBDpjA

点击中间区域
呼出菜单
上一章
目录
下一章
×

打开