web-dev-qa-db-fra.com

Opérateur de tableau C ++ [] avec plusieurs arguments?

Puis-je définir en C++ un opérateur de tableau qui accepte plusieurs arguments? Je l'ai essayé comme ça:

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];       
}

Mais je reçois cette erreur:

error C2804 binary operator '[' has too many parameters
49
genesys

Non, vous ne pouvez pas surcharger operator[] Pour accepter plusieurs arguments. Vous pouvez à la place surcharger operator(). Voir Comment créer un opérateur d'indice pour une classe Matrix? dans la FAQ C++.

44
jamesdlin

Il n'est pas possible de surcharger l'opérateur [] Pour accepter plusieurs arguments, mais une alternative consiste à utiliser modèle proxy.

En deux mots: a[x][y], La première expression (a[x]) Retournerait un type différent, nommé type proxy, qui aurait un autre operator[]. Il appellerait quelque chose comme _storedReferenceToOriginalObject->At(x,y) de la classe d'origine.

Vous ne pourrez pas faire a[x,y], Mais je suppose que vous vouliez quand même surcharger la syntaxe de tableau 2D de style C++ habituelle.

40
Pavel Radzivilovsky

Il y a une petite astuce que vous pouvez faire avec la syntaxe d'initialisation uniforme disponible dans C++ 11. Au lieu de prendre l'index directement, vous prenez 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];
}

Et puis utilisez la nouvelle syntaxe:

my_array<int> arr;
// ...
arr[{1, 2, 3}] = 42;
36
Jiří Pospíšil

Par souci d'exhaustivité: il existe un moyen d'utiliser réellement l'opérateur de parenthèse avec plusieurs arguments, s'il ne s'agit pas de types de données de base, à savoir en surchargeant l'opérateur virgule et non l'opérateur de parenthèse, voir ce qui suit post sur la surcharge de virgules:

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

Avertissement: à mon avis, la surcharge de l'opérateur virgule est sujette aux erreurs et rend le code plus obscur, et ne vaut la peine d'être envisagée que dans des cas plus exotiques. J'ai ajouté cette réponse parce que je suis tombé sur une instance de cela dans du code et il m'a fallu un certain temps pour comprendre que la clé n'était pas l'opérateur [] (qui ne peut pas être surchargé avec plusieurs arguments) mais l'opérateur,.

10
tePer

tableaux à N dimensions de type et de taille arbitraires en C++:

Cette réponse est inspirée de la réponse de Pavel Radzivilovsky, merci pour cela. J'ai eu un peu de mal à réaliser l'implémentation, car c'était ma première tentative de modèles récursifs. J'aimerais partager ce que j'ai fait pour que les autres puissent comprendre plus rapidement que moi.

J'ai écrit une classe de modèle c ++ pour créer un tableau à n dimensions de type et de taille arbitraires. Il doit être instancié avec le type de tableau et le nombre de dimensions. La taille peut être modifiée dynamiquement. J'ai donné ci-dessous une version de travail nue (dépouillée) de la façon de créer un tableau multidimensionnel dont les éléments sont accessibles par application successive de l'opérateur [] (par exemple tableau [x] [y] [z]). Cette version ne peut gérer que des tableaux de dimension n> 1. La fonction principale montre comment créer un tableau d'entiers à 4 dimensions comme exemple.

MODIFIER : gardez à l'esprit que l'exemple ci-dessous est minimal pour la lisibilité, dans qu'il ne désalloue pas le tableau, ni ne vérifie les limites d'accès. L'ajout est trivial et laissé au programmeur.

#include <stdio.h>
#include <stdlib.h>

template <typename T, int N>
struct array {
    array<T,N>() : data(NULL), offset((int*) malloc(sizeof(int)*N)){}
    array<T,N>(T *data, int *offset) : data(data), offset(offset){}
    array<T,N-1> operator[](int i){return array<T,N-1>(&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 <typename T>
struct array<T,1>{
    array<T,1>(T *data, int *offset) : data(data){}
    T& operator[](int i){return data[i];}
    T *data;
};

int main () {
    array<int, 4> 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;
}

Prendre plaisir.

2
gospes