Why isn't this 'for' loop valid?
From C++ Primer 5th Edition by Lippman, page 182, consider:
int ia[3][4];
for (auto row : ia)
for (auto col : row)
The first
for
iterates through ia, whose elements are arrays of size 4. Becauserow
is not a reference, when the compiler initializesrow
it will convert each array element (like any other object of array type) to a pointer to that array’s first element. As a result, in this loop the type ofrow
isint*
.
I am not really sure that I understand how this auto works, but if I can assume it automatically gives a type to a row based on ia
array members type, but I don't understand why this kind of for
, where row is not a reference, is not valid. Why is this going to happen? "pointer to that array’s first element", because of what?
The problem is that row
is an int *
and not a int[4]
as one would expect because arrays decay to pointers and there is no automatic way to know how many elements a pointer points to.
To get around that problem std::array
has been added where everything works as expected:
#include <array>
int main() {
std::array<std::array<int, 4>, 3> ia;
for (auto &row : ia){
for (auto &col : row){
col = 0;
}
}
}
Note the &
before row
and col
which indicate that you want a reference and not a copy of the rows and columns, otherwise setting col
to 0 would have no effect on ia
.
To prevent the decay of the int[]
to int*
you can use &&
int main() {
int ia[3][4];
for (auto && row : ia)
for (auto && col : row)
;
}