Why isn't this 'for' loop valid?

C++ArraysC++11

C++ Problem Overview


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. > Because row is not a reference, when the compiler initializes row 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 of row is int*.

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?

C++ Solutions


Solution 1 - C++

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.

Solution 2 - C++

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)
            ;
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser5585984View Question on Stackoverflow
Solution 1 - C++nwpView Answer on Stackoverflow
Solution 2 - C++ThomasView Answer on Stackoverflow