Почему этот цикл "for" не работает?
Рассмотрим:
int ia[3][4];
for (auto row : ia)
for (auto col : row)
Первый for
выполняет итерацию через ia, элементами которой являются массивы размера 4. Потому что row
не является ссылкой, когда компилятор инициализирует row
, он преобразует каждый элемент массива (как любой другой объект массива type) указателю на первый элемент массива. В результате в этом loop тип row
равен int*
.
Я не уверен, что понимаю, как работает этот авто, но если я могу предположить, что он автоматически дает тип строке на основе типа элементов массива ia
, но я не понимаю, почему этот тип for
, где строка не является ссылкой, недействительна. Почему это произойдет? "указатель на этот массив первый элемент", из-за чего?
Ответы
Ответ 1
Проблема заключается в том, что row
является int *
, а не a int[4]
, как можно было бы ожидать, потому что массивы распадаются на указатели, и нет автоматического способа узнать, сколько элементов указывает указатель.
Чтобы обойти эту проблему, std::array
был добавлен, где все работает так, как ожидалось:
#include <array>
int main() {
std::array<std::array<int, 4>, 3> ia;
for (auto &row : ia){
for (auto &col : row){
col = 0;
}
}
}
Обратите внимание на &
до row
и col
, которые указывают, что вы хотите ссылку, а не копию строк и столбцов, в противном случае установка col
в 0 не повлияет на ia
.
Ответ 2
Чтобы предотвратить распад int[]
до int*
, вы можете использовать &&
int main() {
int ia[3][4];
for (auto && row : ia)
for (auto && col : row)
;
}