c ++ for loops(c ++ 11方式和旧版本方式)

时间:2014-01-09 02:08:24

标签: c++ c++11

我刚开始学习c ++。 我被教会如何编写一个简单的for循环

例如

for (int i = 0; i < vector.size(); i++) {
    //do stuff
}

但现在经常会看到人们在 for for循环中使用 auto 这个词。

假设我有一个包含一些数据的向量,这些数据将被带到地图

e.g

以c ++ 11方式

vector<char> vec;
map<char, int> myMap;
vec.push_back('a');
vec.push_back('b');
vec.push_back('b');
vec.push_back('c');

// Loop through the vector
for (auto x : vec) {
   ++myMap[x]; 
}

for (auto x : myMap) {

}

相当于

vector<char> vec;
map<char, int> myMap;
vec.push_back('a');
vec.push_back('b');
vec.push_back('b');
vec.push_back('c');

for (int x = 0; x < v.size(); x++) {
    ++myMap[v[x]];
}

for (int x = 0; x < myMap.size() x++) {
   //print content in map
}

3 个答案:

答案 0 :(得分:3)

它的效果相当,而不是效率。以下是标准定义的确切翻译:

for (auto element : container) {
  //Stuff
}

被转换为这个基于迭代器的循环:

auto&& __range = container; 
for (auto __itr = std::begin(container),  __end = std::end(container);
     __itr != __end; ++__itr) { 
   element = *__itr;
   //Stuff
}

特别是,这是不同的,因为它只评估结束一次(而不是多次调用v.size())并且它使用迭代器而不是索引。它还提供了一个更清晰的界面:

  1. 你知道必须遍历所有元素(除非你使用break / continue)。
  2. 你知道必须一次循环一个元素(除非你使用break / continue)。
  3. 它隐藏了使用带有语法糖的索引/迭代器:)。
  4. 很少有其他事情:

    1)auto是一个单独的语言功能。您无需使用auto来使用基于范围的for循环,例如:

    for (int i : { 1, 2, 3, 4, 5}) {
       cout << i << endl;
    }
    

    打印数字1-5是完全合法的方式。

    2)不使用push_back来填充示例向量,而是使用'universal initialization`:

    vector<char> vec { 'a', 'b', 'c', 'd' };
    

    3)当使用基于范围的for循环与非基本类型时,更喜欢使用auto&const auto&作为范围声明类型。例如

    vector<string> v { "Hello", "world" };
    for (const auto& elt : v) {
      cout << elt << endl;
    }
    

    我们这样做是因为复制基元以外的东西通常很昂贵,默认情况下会复制副本。这里我们使用别名,为我们保存字符串副本,从而节省分配的性能成本。

    Source

    技术性:我给出的翻译有点不准确,因为它没有以与标准相同的方式处理所有情况(它更喜欢成员函数begin / end和数组得到特殊处理)。我简化了它以便于理解。有关详细信息,请参阅上面的来源。

答案 1 :(得分:1)

您无法取消引用int变量。您的旧样式示例需要稍微更新:

for (int x= 0 ; ( x < v.size() ) ; x ++ ) {
  ++ myMap[ v[x] ] ;
}

但在旧式C ++中没有人真正这样做过,他们使用了迭代器:

for ( vector<int>::iterator itptr= v.begin() ; ( itptr != v.end() ) ; ++ itptr ) {
  ++ myMap[ * itptr ] ;
}

由于auto

,这种形式的for循环在C ++ 11中变得更容易了
for ( auto itptr= v.begin() ; ( itptr != v.end() ) ; ++ itptr ) {
  ++ myMap[ * itptr ] ;
}

但正如您所见,新的for形式是最简单的:

// Loop through the vector
for (auto x : vec) {
 ++myMap[x]; 
}

但请注意我没有取消引用xx就是角色。

答案 2 :(得分:0)

,它们是等效的。

除了这两种情况之外,都应该尝试延迟x,因为在这两种情况下,这都是语法错误。