How does the range-based for work for plain arrays?
Is that to read as, "Tell me what a ranged-for does (with arrays)?"
I'll answer assuming that - Take the following example using nested arrays:
int ia[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
for (auto &pl : ia)
Text version:
ia
is an array of arrays ("nested array"), containing [3]
arrays, with each containing [4]
values. The above example loops through ia
by it's primary 'range' ([3]
), and therefore loops [3]
times. Each loop produces one of ia
's [3]
primary values starting from the first and ending with the last - An array containing [4]
values.
- First loop:
pl
equals {1,2,3,4}
- An array
- Second loop:
pl
equals {5,6,7,8}
- An array
- Third loop:
pl
equals {9,10,11,12}
- An array
Before we explain the process, here are some friendly reminders about arrays:
- Arrays are interpreted as pointers to their first value - Using an array without any iteration returns the address of the first value
pl
must be a reference because we cannot copy arrays
- With arrays, when you add a number to the array object itself, it advances forward that many times and 'points' to the equivalent entry - If
n
is the number in question, then ia[n]
is the same as *(ia+n)
(We're dereferencing the address that's n
entries forward), and ia+n
is the same as &ia[n]
(We're getting the address of the that entry in the array).
Here's what's going on:
- On each loop,
pl
is set as a reference to ia[n]
, with n
equaling the current loop count starting from 0. So, pl
is ia[0]
on the first round, on the second it's ia[1]
, and so on. It retrieves the value via iteration.
- The loop goes on so long as
ia+n
is less than end(ia)
.
...And that's about it.
It's really just a simplified way to write this:
int ia[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
for (int n = 0; n != 3; ++n)
auto &pl = ia[n];
If your array isn't nested, then this process becomes a bit simpler in that a reference is not needed, because the iterated value isn't an array but rather a 'normal' value:
int ib[3] = {1,2,3};
// short
for (auto pl : ib)
cout << pl;
// long
for (int n = 0; n != 3; ++n)
cout << ib[n];
Some additional information
What if we didn't want to use the auto
keyword when creating pl
? What would that look like?
In the following example, pl
refers to an array of four integers
. On each loop pl
is given the value ia[n]
:
int ia[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
for (int (&pl)[4] : ia)
And... That's how it works, with additional information to brush away any confusion. It's just a 'shorthand' for
loop that automatically counts for you, but lacks a way to retrieve the current loop without doing it manually.