¿Cómo hacer que una función reciba una matriz multidimensional de tamaño arbitrario en C ++?

Estaba tratando de hacer una función que tome una matriz como entrada y produzca alguna función en C ++. Pero quiero que funcione en una matriz mxn de tamaño arbitrario. es decir, no puedo especificar en los argumentos de la función los valores de n (doble matriz [] [n]). Porque n será arbitrario. ¿Hay alguna manera de que pueda pasar una matriz mxn bidimensional arbitraria a una función? Agradeciendotelo de antemano. -indiajoe

template  void foo(T (&array)[W][H]) { // Do stuff with array here } 

Hay más de una forma de hacerlo. La mejor forma es probablemente definir una clase de matriz y pasar una referencia constante a una instancia.

 class matrix { double* values; size_t m; size_t n; public: matrix(size_t m_, size_t n_) : m(m_), n_(n) { values = new double[m * n]; } ~matrix() { delete[] values; } double& operator(size_t i, size_t j) { assert(i < m); assert(j < n); return values[i + m * j]; } const double& operator(size_t i, size_t j) const { assert(i < m); assert(j < n); return values[i + m * j]; } private: matrix(const matrix&); matrix& operator =(const matrix&); }; void function(const matrix& matrix); 

Si no desea utilizar una clase y sus datos se almacenan de forma lineal (como en mi clase de matriz), simplemente puede pasar un puntero a un doble y las dimensiones:

 void function(double* values, size_t m, size_t n); 

Si realmente desea usar el doble [m] [n] y tiene una función que acepta cualquier tamaño de matriz, puede convertirlo manualmente en un doble **, haciendo algo como eso:

 void function(double** lines, size_t m, size_t n); void client() { const size_t m = ...; const size_t n = ...; double matrix[m][n]; double* temporary[m]; for (size_t i = 0; i < m; ++ i) { temporary[i] = &matrix[i][0]; } function(temporary, m, n); } 

O, usando una función de plantilla para hacer la conversión:

 void function(double** array, size_t m, size_t n); template < size_t M, size_t N > void function(double array[M][N]) { double* temporary[M]; for (size_t i = 0; i < M; ++ i) { temporary[i] = &array[i][0]; } function(temporary, M, N); } 

Esto se debe a que una matriz solo puede decaer una vez a un puntero (es decir, doble [n] decaimiento a doble *, pero doble [m] [n] decaimiento a doble * [n]).

utilizando la biblioteca estándar de C ++, puedes hacer eso:

 typedef std::vector Dim; typedef std::vector Matrix; void workOnMatrix(Matrix& matrix) { } 

EDITAR: elimino la referencia a STL ya que STL de SGI y la biblioteca estándar de C ++ no son las mismas cosas. Tan diferentes parecen ser que no deben tomarse una por otra.

Podrías hacerlo a la manera de Tomalak, pero ciertamente no lo recomendaría. Nunca podría llamar a esa función desde otra que no fuera también una plantilla si la matriz se pasaba a través de parámetros. Esto significa que casi todo su progtwig tendría que ser un código de plantilla. OK, en teoría, pero en general poco práctico.

No puedes usar la interfaz double** como has descubierto. Podría convertir a ese tipo, pero también necesita que se pase la información de tamaño para poder:

 my_ptrptr[row * col_size][col]; 

Tienes que ser explícito acerca de las dimensiones como esta porque el comstackdor ya no sabe lo que necesita.

La mejor respuesta a tu problema es no hacerlo de esa manera. Aprovecha el STL para que no tengas que lidiar con esta mierda de Hokey como esta. Usa la respuesta de Stephane.

Sin embargo, otra cosa que puedes hacer, si vas a usar plantillas de todos modos, es escribirlas para que sean genéricas:

 template < typename Iter > void fun(Iter begin, Iter end) { // begin[x][y]... (*begin)[y]...++begin, etc... } ... double arr[arr_row_count][arr_col_count]; fun(arr, arr+arr_row_count); 

Este tiene el mayor beneficio de trabajar con CUALQUIER COSA que se parece a una serie de matrices. Esto significa que sería un excelente método ‘interino’ que puede usar con los tipos double[][] hasta que pueda comenzar a usar algo mejor como std::vector y / o boost::array . Hágalo a la manera de Tomalak y no podrá hacer este cambio más tarde … otra razón más para no usar ese método.