c++arraysfor-looppointersauto

Why does auto works differently in "range for" in 2D and 1D arrays in C++


Hi I am working with 2D and 1D arrays in C++ and using range for to access elements.The code that i am using is as follows:

For 2D Arrays

int ia[3][4] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
for (auto& row : ia) {
    for (auto col : row) {
        cout << col << endl;
    }
}

For ID Array

int base_array[2] = { 1, 2 };
for (auto p : base_array) {
    std::cout << p << std::endl;
}

So as we can see in the outside range for loop of 2D array, the control variable row must be of reference type so that the automatic array to pointer conversion does not happen and we can loop through the elements which themselves are arrays of size 4. But in the 1D array we are not using the control variable p as a reference type and even then we are able to traverse through the 1D array. My question is why in the 1D array the array to pointer conversion is not taking place? How is it working without the control variable being of reference type? That is, why (how) is p of int type instead of int* in 1D array case while if we omit the reference symbol in the control variable row it will then become a int* but when we include the reference symbol in front of variable row then it will become an array type. Why there is this difference in behavior?


Solution

  • Case 1(Without reference symbol infront of row)

    For the outside loop, the loop variable row is initialized to the first element of ia which is itself an array and since we're not using reference here, so the array to pointer conversion will take place and row will become int*. And since we cannot loop through an int*, we get an error when we try to do so in the inner for loop.

    Case 2(With reference symbol infront of row)

    When we add reference symbol infont of row, then row will be deduced as int(&)[4], meaning a reference to an array of size 4 with elements of type int. And since we can loop through this, the inner loop works here.