在c ++ 11中,如果我在向量上使用基于范围的循环,它会保证迭代顺序吗? 比方说,对于相同的输出,是否可以保证以下代码块?
vector<T> output;
vector<U> V;
for( auto v: V) output.push_back(f(v));
vs
for(int i =0; i < V.size(); ++i) output.push_back(f(V[i]));
如果不是vector
而是map
等怎么办?
答案 0 :(得分:15)
是的,这两个代码保证会这样做。虽然我没有指向标准的链接,但您可以查看here。我引述:You can read that as "for all x in v" going through starting with v.begin() and iterating to v.end().
答案 1 :(得分:13)
是的,它们是等价的。 6.5.4中的标准保证:
对于基于范围的表格形式
for(for-range-declaration:expression)statement
让range-init等同于括号(表达式)
所包围的表达式以及表单
的基于范围的for语句for(for-range-declaration:braced-init-list)statement
让range-init等同于braced-init-list。在每种情况下,基于范围的for语句等同于
{
auto && __range = range-init;
for ( auto __begin = begin-expr,
__end = end-expr;
__begin != __end;
++__begin ) {
for-range-declaration = *__begin;
statement
}
}
其中__range,__ begin和__end是仅为exposition定义的变量,_RangeT是表达式的类型,begin-expr和end-expr确定如下: 表达式,begin-expr和end-expr确定如下:
- 如果_RangeT是一个数组类型,则begin-expr和end-expr分别是__range和__range + __bound,其中__bound是数组绑定的。如果_RangeT是一个未知大小的数组或一个类型不完整的数组,那么该程序就是格式不正确的;
- 如果_RangeT是类类型,则在类_RangeT的范围内查找unqualified-ids的开始和结束 好像通过类成员访问查找(3.4.5),如果其中任何一个(或两者)找到至少一个声明,开始 - expr和end-expr分别是__range.begin()和__range.end();
- 否则,begin-expr和end-expr分别是begin(_ range)和end( _range),其中begin和end用参数依赖查找查找(3.4.2) )。出于此名称查找的目的,namespace std是一个关联的命名空间。
虽然你对地图的问题有点荒谬。如果它是一个有序的地图,你正确地迭代地图,那么它们是等价的。如果这是一张无序的地图,那么你的问题并没有多大意义。
答案 2 :(得分:10)
是和否(这取决于使用的容器):
示例:
#include <iostream>
#include <map>
int main()
{
typedef std::map<int, int> map;
map m = { { 0, 0 }, { 2, 2 }, { 4, 4 } };
for(const auto& e : m) {
std::cout << e.first << " ";
}
std::cout << std::endl;
for(map::size_type i = 0; i < m.size(); ++i) {
std::cout << m[i] << " ";
}
std::cout << std::endl;
return 0;
}
结果是:
0 2 4
0 0 2 0 4
(第二个结果可能是一个很好的镜头,甚至是自己的意图)