在c ++ 11中,如果我在向量上使用基于范围的循环,它会保证迭代顺序吗?比方说,以下代码块是否可以保证相同的输出?
vector<T> output;
vector<U> V;
for( auto v: V) output.push_back(f(v));
Run Code Online (Sandbox Code Playgroud)
VS
for(int i =0; i < V.size(); ++i) output.push_back(f(V[i]));
Run Code Online (Sandbox Code Playgroud)
如果它是什么不是vector
,但map
等?
Omn*_*ity 15
是的,它们是等价的.6.5.4中的标准保证:
对于基于范围的表单声明
for(range-declaration:expression)语句
让range-init等同于括号括起来的表达式(表达式)
以及基于范围的表格声明
for(range-declaration:braced-init-list)语句
让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
}
}
Run Code Online (Sandbox Code Playgroud)
其中__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)一样,并且如果其中任何一个(或两者)找到至少一个声明, begin-expr和end-expr分别是__range.begin()和__range.end();
- 否则,begin-expr和end-expr分别是begin(_ range)和end( _range),其中begin和end用参数依赖查找(3.4.2)查找.出于此名称查找的目的,名称空间std是关联的名称空间.
虽然你对地图的问题有点荒谬.如果它是一个有序的地图,你正确地迭代地图,那么它们是等价的.如果这是一张无序的地图,那么你的问题并没有多大意义.
小智 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;
}
Run Code Online (Sandbox Code Playgroud)
结果是:
0 2 4
0 0 2 0 4
Run Code Online (Sandbox Code Playgroud)
(第二个结果可能是自己的脚或甚至打算很好的射击)