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

Vio*_*ffe 2 c++ foreach c++11

我有以下代码:

for (auto it = _locations.locations().begin(); it != _locations.locations().end(); ++it)
   // Do something
Run Code Online (Sandbox Code Playgroud)

我想替换它

for (const auto& location: _locations.locations())
   // Do something
Run Code Online (Sandbox Code Playgroud)

但后来意识到我不知道它是如何起作用的.是否会在locations()每次迭代时调用该方法,或者是否会在本地"缓存"容器表达式求值的结果,从而只导致一次locations()调用?标准是否以这种或那种方式定义了这种行为?

Jer*_*fin 7

是的,它需要被"缓存".

§[stmt.ranged]/1说:

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

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

因此,这需要begin-exprend-expr各只被调用一次(虽然,当然,这是受正常"的,如果"规则,所以这是如有更改,如果,例如,他们没有观察到的副作用).

  • @VioletGiraffe返回包含每次调用`begin` /`end`的容器的迭代器.这不是一个好主意:迭代迭代时变异的容器通常**不能可靠地工作**,当它失败时,它将以难以预测的方式失败.在迭代容器时不要改变容器. (2认同)