基于范围的 for 循环是否缓存容器表达式,或每次迭代重新计算它

Does the range-based for loop cache the container expression, or re-evaluate it each iteration?

本文关键字:迭代 新计算 计算 表达式 范围 于范围 for 循环 缓存 是否      更新时间:2023-10-16

我有以下代码:

for (auto it = _locations.locations().begin(); it != _locations.locations().end(); ++it)
   // Do something

我想用

for (const auto& location: _locations.locations())
   // Do something

但后来意识到我不知道它将如何工作。每次迭代都会调用 locations() 方法,还是将容器表达式计算的结果"缓存"在本地,导致只有一个locations()调用?标准是否以一种或另一种方式定义了这种行为?

是的,它需要"缓存"。

§[stmt.ranged]/1 说:

在每种情况下,基于范围的 for 语句等效于

{
    auto && __range = range-init;
    for ( auto __begin = begin-expr,
               __end = end-expr;
               __begin != __end;
               ++__begin ) {
                   for-range-declaration = *__begin;
                   statement
              } 
}

因此,这要求begin-exprend-expr分别只调用一次(当然,这受制于正常的"as-if"规则,因此,例如,如果它们没有可观察到的副作用,则可能会发生变化)。