C ++ operador de matriz con múltiples argumentos?

¿Puedo definir en C ++ un operador de matriz que toma múltiples argumentos? Lo intenté así:

const T& operator[](const int i, const int j, const int k) const{ return m_cells[k*m_resSqr+j*m_res+i]; } T& operator[](const int i, const int j, const int k){ return m_cells[k*m_resSqr+j*m_res+i]; } 

Pero estoy obteniendo este error:

 error C2804 binary operator '[' has too many parameters 

No, no puede sobrecargar al operator[] para aceptar múltiples argumentos. En su lugar, puede sobrecargar el operator() . Consulte ¿Cómo creo un operador de subíndices para una clase Matrix? de las preguntas frecuentes de C ++.

No es posible sobrecargar al operador [] para aceptar múltiples argumentos, pero una alternativa es usar el patrón de proxy .

En dos palabras: a[x][y] , la primera expresión ( a[x] ) devolvería un tipo diferente, denominado tipo de proxy, que tendría otro operator[] . _storedReferenceToOriginalObject->At(x,y) algo como _storedReferenceToOriginalObject->At(x,y) de la clase original.

No podrás hacer a[x,y] , pero supongo que querías sobrecargar la syntax de matriz 2D de estilo C ++ habitual.

Hay un buen truco que puedes hacer con la syntax de inicialización uniforme disponible en C ++ 11. En lugar de tomar el índice directamente, tomas un POD.

 struct indices { std::size_t i, j, k; }; T& operator[](indices idx) { return m_cells[idx.k * m_resSqr + idx.j * m_res + idx.i]; } 

Y luego usa la nueva syntax:

 my_array arr; // ... arr[{1, 2, 3}] = 42; 

Para mayor completitud: hay una forma de usar realmente el operador de corchetes con múltiples argumentos, si no son tipos de datos básicos, es decir, al sobrecargar al operador de coma y no al operador de corchete, consulte la siguiente publicación sobre sobrecarga de coma:

https://stackoverflow.com/a/18136340/5836981

Descargo de responsabilidad: en mi opinión, la sobrecarga del operador de coma es propensa a errores y hace que el código sea más oscuro, y vale la pena considerarlo solo en casos más exóticos. Agregué esta respuesta porque encontré una instancia de esto en algún código y me tomó un tiempo darme cuenta de que la clave no era el operador [] (que no se puede sobrecargar con múltiples argumentos) sino el operador.

Matrices N-dimensionales de tipo y tamaño arbitrarios en C ++:

Esta respuesta está inspirada en la respuesta de Pavel Radzivilovsky, gracias por eso. Me costó un poco darme cuenta de la implementación, ya que fue mi primera puñalada en plantillas recursivas. Me gustaría compartir lo que hice para que otros puedan entenderlo más rápido que yo.

Escribí una clase de plantilla c ++ para crear una matriz n-dimensional de tipo y tamaño arbitrario. Necesita ser instanciado con el tipo de matriz y el número de dimensiones. El tamaño se puede cambiar dinámicamente. He dado a continuación una versión de trabajo desnuda (despojada) de cómo crear una matriz multidimensional a la que se puede acceder a los elementos mediante la aplicación sucesiva del operador [] (por ejemplo, matriz [x] [y] [z]). Esta versión solo puede manejar matrices de dimensión n> 1. La función principal muestra cómo crear una matriz de enteros de 4 dimensiones como ejemplo.

EDITAR : tenga en cuenta que el ejemplo a continuación es mínimo para la legibilidad, ya que no desasigna la matriz, ni tampoco limita el acceso. Agregar esto es trivial y se lo deja al progtwigdor.

 #include  #include  template  struct array { array() : data(NULL), offset((int*) malloc(sizeof(int)*N)){} array(T *data, int *offset) : data(data), offset(offset){} array operator[](int i){return array(&data[i*offset[N]], offset);} bool resize(int *size){ offset[N-1] = 1; int total_size = size[N-1]; for(int i = N-2; i >= 0; i--){ total_size *= size[i]; offset[i] = offset[i+1]*size[i+1]; } return (data = (T*) realloc (data, total_size*sizeof(T))); } T *data; int *offset; }; template  struct array{ array(T *data, int *offset) : data(data){} T& operator[](int i){return data[i];} T *data; }; int main () { array a; // create array with dimensions [1][3][3][7] int size[4] = { 1, 3, 3, 7 }; a.resize(size); a[0][1][2][3] = 123; return 0; } 

Disfrutar.