在c ++ 11中,如果我在向量上使用基于for循环的范围,它会保证迭代顺序吗?
即以下代码块是否保证产生相同的输出?
vector<T> output;
vector<U> V;
for( auto v: V) output.push_back(f(v));
对比
for(int i =0; i < V.size(); ++i) output.push_back(f(V[i]));
如果不是vector
butmap
等怎么办?
是的,这两个代码保证做同样的事情。虽然我没有标准的链接,但您可以在这里查看。我引用:You can read that as "for all x in v" going through starting with v.begin() and iterating to v.end().
是的,它们是等价的。6.5.4 中的标准保证:
对于形式的基于范围的 for 语句
for ( for-range-declaration : expression ) statement
let
range-init
等价于括号括起来的表达式 ( expression )和基于范围的 for 形式的声明
for ( for-range-declaration : braced-init-list ) statement
let
range-init
等价于花括号初始化列表。在每种情况下,基于范围的 for 语句等效于
{
auto && __range = range-init;
for ( auto __begin = begin-expr,
__end = end-expr;
__begin != __end;
++__begin ) {
for-range-declaration = *__begin;
statement
}
}
其中
__range
、__begin
和__end
是仅为说明而定义的变量,_RangeT
是表达式的类型,begin-expr
和end-expr
确定如下:— if
_RangeT
是一个数组类型,begin-expr
并且end-expr
分别是__range
和__range + __bound
,__bound
数组绑定在哪里。如果_RangeT
是一个未知大小的数组或一个不完整类型的数组,则程序是非良构的;— 如果
_RangeT
是类类型,则在类范围内查找非限定 IDbegin
和 ,就像通过类成员访问查找 (3.4.5) 一样,并且如果其中一个(或两者)找到至少一个声明,并且是和,分别;end
_RangeT
begin-expr
end-expr
__range.begin()
__range.end()
— 否则,
begin-expr
和end-expr
是begin(__range)
和end(__range)
,分别在哪里begin
和end
用依赖于参数的查找(3.4.2)进行查找。出于此名称查找的目的,命名空间std
是一个关联的命名空间。
尽管您关于地图的问题有点荒谬。如果它是有序地图并且您正确地遍历地图,那么它们是等价的。如果它是一个无序的地图,那么你的问题并没有多大意义。
是和否(取决于使用的容器):
例子:
#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
(第二个结果可能是一脚好球,甚至是故意的)