C++ 将基于c++;保持索引顺序
在c++11中,如果我使用基于范围的for循环on vector,它会保证迭代顺序吗? 比如,以下代码块是否保证相同的输出C++ 将基于c++;保持索引顺序,c++,c++11,C++,C++11,在c++11中,如果我使用基于范围的for循环on vector,它会保证迭代顺序吗? 比如,以下代码块是否保证相同的输出 vector<T> output; vector<U> V; for( auto v: V) output.push_back(f(v)); 矢量输出; 向量V; 用于(自动v:v)输出。向后推(f(v)); vs 用于(inti=0;i
vector<T> output;
vector<U> V;
for( auto v: V) output.push_back(f(v));
矢量输出;
向量V;
用于(自动v:v)输出。向后推(f(v));
vs
用于(inti=0;i
如果它不是
向量
,而是映射
等呢 是的,这两种代码保证具有相同的功能。虽然我没有标准的链接,但你可以看看。我引用:您可以将其理解为“v中的所有x”从v.begin()开始,迭代到v.end()。
是和否(取决于使用的容器):
- 基于范围的for类似于for(迭代器pos=range.begin();pos= range.end();++pos){/*带有范围变量=*pos*/…}
- 运算符[]可能会执行不同的操作(例如,如果键不存在,std::map运算符会查找该键并创建一个新条目)
#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;
}
(第二个结果可能是对自己的脚开了一枪,甚至是有意的)是的,它们是等效的。6.5.4中的标准保证: 对于窗体的基于范围的For语句
for(用于范围声明:表达式)语句
让range init
等价于用括号括起来的表达式(表达式)
和基于范围的for语句的形式
for(用于范围声明:带括号的init list)语句
让range init
等效于带括号的init列表。在每种情况下,基于范围的for语句都等效于
其中\uuuu range
、\uuu begin
和\uuuu end
是仅为说明而定义的变量,\u range
是表达式的类型,begin expr
和end expr
确定如下:
-如果\u range
是一种数组类型,begin expr
和end expr
分别是\u range
和\u range+\u-bound
,其中\u-bound
是数组绑定。如果\u range
是大小未知的数组或类型不完整的数组,则程序格式不正确
-如果\u range
是类类型,则在类\u range
的范围内查找不合格的IDbegin
和end
就像按类成员访问查找(3.4.5)一样,如果其中一个(或两者)找到至少一个声明,begin expr
和end expr
分别是\uu range.begin()
和\uu range.end()
-否则,begin expr
和end expr
分别是begin(\uuuu范围)
和end(\uu范围)
,其中begin
和end
通过依赖于参数的查找进行查找(3.4.2)。为了进行名称查找,名称空间std
是一个关联的名称空间
虽然你关于地图的问题有点荒谬。如果它是一个有序的映射,并且你正确地遍历了映射,那么它们是等价的。如果它是一个无序的映射,那么您的问题就没有多大意义。或对表达式中的每个元素重复并顺序执行语句。您可能应该指出,在本例中,无论哪种方式,用户都犯了严重错误。如果在键类型为int
的map
上有顺序索引,则不应使用map
,而应使用deque
或向量
或数组
。如果没有顺序索引,那么应该使用迭代器进行迭代,而不是使用for(int i=0;i
您当然可以通过执行auto&
而不是auto
来优化一些不必要的副本
#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
{
auto && __range = range-init;
for ( auto __begin = begin-expr,
__end = end-expr;
__begin != __end;
++__begin ) {
for-range-declaration = *__begin;
statement
}
}