现代C++编程实战:132个核心技巧示例(原书第2版)
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

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表达式只求值一次,而不是每次迭代循环时都求值,这将会提高性能。