基于C ++ 11范围的循环:它是如何工作的

时间:2015-11-05 22:42:27

标签: c++ c++11

我知道这个循环是如何工作的,以及如何在实际问题中使用它。但我想知道引擎盖下发生了什么。 我认为这个循环类似于常规for循环,例如

for(int i = 0 ; i < 5 ; i ++){
 // instructions
}

变量i只初始化一次,所以我认为这对于基于范围的循环来说是相同的。但是,如果我写这个代码:

for(const int x : vec) {
cout << x << endl;
}

编译器让我这样做,但我不明白这是怎么回事。如果变量xconst,那么x值在每次迭代中是如何变化的?

3 个答案:

答案 0 :(得分:11)

循环的每次迭代都会创建一个局部变量x并将其初始化为vec的下一个元素。当循环迭代结束时,x超出范围。永远不会修改单个x

有关精确的语义,请参阅http://en.cppreference.com/w/cpp/language/range-for

答案 1 :(得分:2)

在这方面,基于范围的for循环确实与经典的for循环有些不同。与经典的for循环相比,您提供的声明(const int x)声明为每次迭代

更确切地说:

for (const int x : vec) {
    cout << x << endl;
}

只是以下“经典迭代器循环”的简写(并简单地替换为):

for (auto it = vec.begin(), e = vec.end(); it != e; ++it) { 
    const int x = *it; 
    cout << x << endl; 
}

(除了ite在正文中不可用; vec实际上是“保存”在一个单独的变量中;但是我们不要只关注这里不重要的细节;可以查找基于范围的for循环的精确定义here

请注意,const int x已在循环体内声明并初始化为*it!所以它在每个迭代中初始化,而不是更改

答案 2 :(得分:1)

对于uncomtanding目的,您可以将其视为编译器正在用for (auto x: y) {...}替换for (auto i = begin(y), end = end(y); i != end; ++i) { auto x = *i; {...} }

对于std :: vector begin(y) / end(y)将解析(通过https://jsfiddle.net/scadp0ar/)到std::begin(y) / std::end(y)版本的y.begin()分别是/ y.end()