这段代码会在每次迭代中获取元素吗?
Would this code fetch the elements every iteration?
通常情况下,我会这样写代码。
auto elements = get_elements();
for(auto i : elements)
{
// ...
}
我想知道使用下面的代码是否会产生任何性能差异。get_elements()
是每次迭代都被调用还是只调用一次?
for(auto i : get_elements())
{
// ...
}
此外,传统的for循环呢?如果我不修改我循环的元素,编译器会优化代码不调用get_elements()
每次迭代吗?
for(auto i = get_elements().begin(); i != get_elements().end(); ++i)
{
// ...
}
与往常一样,当涉及到性能时,您应该用测量来支持您的假设。我想知道使用下面的代码是否会使性能有所不同
没有其他证据表明在特定例程中存在瓶颈,这应该成为放弃更清晰,更简单的设计而支持更复杂,更不直观的设计的理由。根据定义,这将是过早优化。
因此,选择最能传达其意图的形式。这就是说,我可以回答以下问题:每次迭代都调用
get_elements()
还是只调用一次?
不,它只会被调用一次。c++ 11标准第6.5.4/1段规定了这种行为:
对于形式为
的基于范围的For语句for ( for-range-declaration : expression ) statement
令
中的表达式range-init
等价于括号( expression )
[…一个基于范围的for语句是等价的
{ auto && __range = range-init; // <== HERE IS YOUR get_elements()! for ( auto __begin = begin-expr, __end = end-expr; __begin != __end; ++__begin ) { for-range-declaration = *__begin; statement } }
关于你的第二个问题:
此外,传统的for循环呢?
这些只是不太清楚循环本身的目的,更容易出错。我建议避免手动循环。
例如,只看它的第一行,就可以明显看出基于范围的for
循环的目的是遍历集合的所有元素。对于手动展开的for
循环来说,同样的情况并不明显,仅通过查看第一行,您不知道i
变量是否会在循环内被增加或操作。
Herb Sutter在这篇文章中对此进行了很好的讨论(参见问题2-a的解决方案)。
相关文章:
- Boost Spirit,获取迭代器内部语义动作
- 对于set上的循环-获取next元素迭代器
- 如何获取pcl迭代最近点(ICP)的迭代点数?
- 如何在C++中仅获取容器内类成员的迭代器
- C++如何获取传递给函数(STL 迭代器)的参数的名称
- 从 QMap<K、T> 获取 Java 样式迭代器,而不指定 T、K
- 获取 c++ 中具有恒定长度的数组的迭代器
- 使用 declval 获取非常量迭代器
- 如何在每次迭代后在循环中获取变量的值?
- 使用列表迭代器获取所有值
- 从命名空间获取具有相同签名的函数,并在C++中迭代它们
- 如何为获取 stl 容器迭代器的函数提供函数签名?
- 包装 C API 通过C++接受迭代器的函数获取原始指针
- 如何从该列表的元素中获取 std::list<T>::迭代器?
- 使用“decltype”获取迭代器的类型
- 如何使用find_if获取最后一个迭代器
- 从 for(int &i : i) 获取当前迭代器
- 如何从迭代器获取列表
- 范围 V3:获取基本迭代器
- 通过 c++ 中的迭代器从向量中获取相邻的元素对