C++ 将基于c++;保持索引顺序

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

在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

如果它不是
向量
,而是
映射
等呢

是的,这两种代码保证具有相同的功能。虽然我没有标准的链接,但你可以看看。我引用:
您可以将其理解为“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
的范围内查找不合格的ID
begin
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
  }
}