Когда массив передается в качестве параметра функции (передача по значению), он превращается в указатель на первый элемент массива. Даже если вы можете четко прочитать в сигнатуре размеры массива, эти измерения игнорируются компилятором. Такое поведение совместимо с C.
Используя C ++, вы можете передавать массив по ссылке, и это больше не будет проблемой.
int extract_value( int (&a)[10][10], int row, int col ) {
return a[row][col];
}
int main() {
int a[10][10] = {};
a[5][5] = 1;
std::cout << extract_value( a, 5, 5 ) << std::endl;
int b[5][5];
// extract_value( b, 2, 2 ); // error: the function takes an array of 10x10
}
Параметр функции должен точно соответствовать, то есть он принимает только массив 10х10 элементов. Вы можете избавиться от этого ограничения, шаблонизируя функцию по размерам массива. После того, как вы на это, также введите:
template <typename T, int Rows, int Cols>
T extract_value( T (&a)[Rows][Cols], int row, int col ) {
return a[row][col];
}
int main() {
int a[5][7] = {};
extract_value( a, 3, 4 );
int b[8][2] = {};
extract_value( b, 7, 1 ); // correct, the compiler matches sizes
double c[4][4] = {};
extract_value( c, 2, 2 ); // different types are allowed
}
Это решение все еще громоздко в том смысле, что размеры должны быть постоянными времени компиляции, а массив должен быть выделен в стеке. Решением этой проблемы является определение некоторого класса, который занимает динамическую память в буфере (линейном) и имеет преобразование из N-координатной системы в одномерный массив для получения значений, как это было предложено ранее. Вы можете получить некоторые подсказки о том, как это сделать, в этом FAQ о перегрузке операторов, которая обеспечивает реализацию двумерной матрицы. Как только вы это реализовали, вы можете просто использовать это как параметр для функций / методов.
Я бы порекомендовал следовать этому последнему пути: инкапсулировать N-мерный массив в класс, который обеспечивает преобразования в одномерный вектор (в C ++ FAQ Lite используется необработанный указатель, я предпочитаю контейнеры STL).