AC Voltage
AC Voltage

Reputation: 349

C++11 range based loop: How does it really work

I know how this loop works, and how I can use it in practical problems. But I want to know what is happening under the hood. I thought that this loop was similar to a regular for loop in which for example

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

Variable i is initialized only once, so I thought that this was the same for range based loops. But if I for example write this code:

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

The compiler lets me to do this, but I don't understand how this is possible. If variable x is const, how come in every iteration the x value is different?

Upvotes: 12

Views: 4454

Answers (3)

Brian Bi
Brian Bi

Reputation: 119069

Every iteration of the loop creates a local variable x and initializes it to the next element of vec. When the loop iteration ends, x goes out of scope. A single x is never modified.

See this link for the precise semantics.

Upvotes: 18

bobah
bobah

Reputation: 18864

For unterstanding purpose you can think of it as if the compiler is replacing for (auto x: y) {...} with for (auto i = begin(y), end = end(y); i != end; ++i) { auto x = *i; {...} }.

For std::vector begin(y)/end(y) will resolve (via the adl) to std::begin(y)/std::end(y) versions that would call y.begin()/y.end() respectively.

Upvotes: 2

leemes
leemes

Reputation: 45665

The range-based for-loop is indeed somewhat different than the classical for-loop in this regard. The declaration you provide (const int x) is declared for every iteration separately, in contrast to classical for-loops.

To be more precise:

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

is just a shorthand for (and simply replaced with) the following "classical iterator loop":

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

(except that it and e are not available in the body; also vec is actually "saved" in a separate variable; but let's not focus on unimportant details here; the exact definition of range-based for loop can be looked up here)

Note that const int x is declared and initialized to *it inside the loop body! So it is initialized in every iteration, rather than changed.

Upvotes: 3

Related Questions