我知道这个循环是如何工作的,以及如何在实际问题中使用它。但我想知道引擎盖下发生了什么。
我认为这个循环类似于常规for
循环,例如
for(int i = 0 ; i < 5 ; i ++){
// instructions
}
变量i
只初始化一次,所以我认为这对于基于范围的循环来说是相同的。但是,如果我写这个代码:
for(const int x : vec) {
cout << x << endl;
}
编译器让我这样做,但我不明白这是怎么回事。如果变量x
是const
,那么x
值在每次迭代中是如何变化的?
答案 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;
}
(除了it
和e
在正文中不可用; 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()
。