Question: When iterating through a multidimensional array like so:

```
int arr[2][2] = {{6, 7}, {8, 3}, {5, 2}};
for (auto &row : arr) {
    for (auto &cell : row) {
        // code
    }
}

```

What is the type of `row` and `cell` and why must you use a reference?

Answer: 
When you don't use a reference array-to-pointer conversion kicks in and `row` is of type pointer to an array of two `int`s (`int(*)[2]`). The inner loop is then ill-formed because for it to work you need either:

* a type that has `begin` and `end` member functions that return iterators,
* `begin` and `end` free functions that are found by argument dependent lookup and return iterators or
* for array types, `x` and `x + bound` are used for `begin` and `end`, respectively, where `x` is the range and `bound` is the array bound.

`int(*)[2]` doesn't fullfile these conditons. OTOH, when you use `auto&`, you get `int(&)[2]` and the third bullet applies.

P.S. You've got too many initializers for `int[2][2]`.
`row` is an array of `int`s. `cell` is a reference to an `int`. You need a reference if you want to modify the contents of `cell`, because otherwise the loop variable will be a copy.