[c++] Tableau multidimensionnel: surcharge de l'opérateur


Answers

vsoftco a tout à fait raison, vous devez implémenter un opérateur de surcharge si vous voulez réellement accéder à vos éléments. Ceci est nécessaire si vous voulez que ce soit dynamique, c'est ainsi que vous le décrivez. En fait, je pensais que c'était un problème intéressant, alors j'ai implémenté ce que vous avez décrit comme un modèle. Je pense que cela fonctionne, mais quelques petites choses pourraient être légèrement décalées. Voici le code:

template<typename T>
class nDimArray {
    using thisT = nDimArray<T>;

    T                    m_value;
    std::vector<thisT*>  m_children;
public:
    nDimArray(std::vector<T> sizes) {
        assert(sizes.size() != 0);
        int thisSize = sizes[sizes.size() - 1];
        sizes.pop_back();

        m_children.resize(thisSize);
        if(sizes.size() == 0) {
            //initialize elements
            for(auto &c : m_children) {
                c = new nDimArray(T(0));
            }
        } else {
            //initialize children
            for(auto &c : m_children) {
                c = new nDimArray(sizes);
            }
        }
    }
    ~nDimArray() {
        for(auto &c : m_children) {
            delete c;
        }
    }
    nDimArray<T> &operator[](const unsigned int index) {
        assert(!isElement());
        assert(index < m_children.size());
        return *m_children[index];
    }

    //icky dynamic cast operators
    operator T() {
        assert(isElement());
        return m_value;
    }
    T &operator=(T value) {
        assert(isElement());
        m_value = value;
        return m_value;
    }

private:
    nDimArray(T value) {
        m_value = value;
    }

    bool isElement() const {
        return m_children.size() == 0;
    }

    //no implementation yet
    nDimArray(const nDimArray&);
    nDimArray&operator=(const nDimArray&);
};

L'idée de base est que cette classe peut soit agir comme un tableau de tableaux, soit comme un élément. Cela signifie qu'en fait un tableau de tableaux pourrait être un tableau d'éléments! Lorsque vous voulez obtenir une valeur, elle essaie de la convertir en un élément, et si cela ne fonctionne pas, elle renvoie simplement une erreur d'assertion.

J'espère que c'est logique, et bien sûr, si vous avez des questions, demandez! En fait, j'espère que vous posez la question parce que l'ampleur du problème que vous décrivez est plus grande que vous ne le pensez probablement.

Question

J'ai une classe avec un tableau multidimensionnel:

  • il est possible de créer un tableau de dimensions un, deux, ..., n avec cette classe

  • si le tableau a n dimensions, je veux utiliser n operator[] pour obtenir un objet:

Exemple:

A a({2,2,2,2}]; 
a[0][1][1][0] = 5;

mais le tableau n'est pas un vecteur de pointeur qui conduit à d'autres vecteurs etc ...

donc je veux que l'opérateur [] retourne un objet de classe jusqu'à la dernière dimension, puis retourne un entier

C'est un code fortement simplifié, mais cela montre mon problème:

L'erreur que je reçois: "[Error] cannot convert 'A::B' to 'int' in initialization"

#include <cstddef>     // nullptr_t, ptrdiff_t, size_t
#include <iostream>    // cin, cout...

class A {
    private:
        static int* a;
    public:
        static int dimensions;
        A(int i=0) { 
            dimensions = i;
            a = new int[5];
            for(int j=0; j<5; j++) a[j]=j; 
        };

        class B{
            public:
                B operator[](std::ptrdiff_t);
        };
        class C: public B{
            public:
                int& operator[](std::ptrdiff_t);
        };

        B operator[](std::ptrdiff_t);
};

//int A::count = 0;

A::B A::operator[] (std::ptrdiff_t i) {
    B res;
  if (dimensions <= 1){
    res = C();
}
  else{
    res = B();
  }
  dimensions--;
  return res;
}

A::B A::B::operator[] (std::ptrdiff_t i){
    B res;
    if (dimensions <=1){
        res = B();
    }
    else{
        res = C();
    }
    dimensions--;
    return res;
}

int& A::C::operator[](std::ptrdiff_t i){
    return *(a+i);
}


int main(){
    A* obj = new A(5);
    int res = obj[1][1][1][1][1];
    std::cout<< res << std::endl;
}



Links