2010-09-10 23 views
2

J'ai un petit problème en C++ je ne sais pas comment résoudre. La première partie du problème consiste à accéder à un élément dans une structure via [], ou mieux, pour mapper [] à un sous-élément.C++ [] mappage, éventuellement à travers des modèles

Mon struct ressemble à ceci:

struct e { 
    std::string content; 
    std::string name; 
    std::map<std::string, std::vector<e> > elements; 
}; 

Si je veux accéder à un sous-élément e, je peux le faire comme ceci: e.elements["e1"][0].elements["e1sub"][0].content, serait-il possible de cartographier ce que je peux appeler comme ça : e["e1"][0]["e1sub"][0], cela signifierait juste qu'il doit "remplacer" chaque e [] par e.elements [].

Peut-être que cela peut être fait avec des modèles mais je ne sais pas encore comment les utiliser car je commence à peine à apprendre le C++.

Merci d'avance pour toute aide, Robin.

+0

est-ce pas un vecteur '' techniquement illégal dans les 'struct e' (vecteur de type incomplet, mais en fonction des détails de mise en œuvre, vous pouvez sortir avec elle)? – visitor

+0

Recommande de faire de 'elements' un membre privé/protégé en plus de toutes les suggestions données ci-dessous – Chubsdad

Répondre

4

Vous devez surcharger operator[]. Généralement, vous voulez implémenter deux versions de cet opérateur, mais puisque std::map ne surcharge que la version non const, cela pourrait vous suffire.

Quelque chose comme ce qui suit devrait faire:

struct e { 
    std::string content; 
    std::string name; 
    std::map<std::string, std::vector<e> > elements; 

    std::vector<e>& operator[](const std::string& key) {return elements[key];} 
}; 
+4

C'est une bonne réponse, mais si vous surchargez les opérateurs, peut-être est-il temps de mettre les données dans une vraie classe? – Falmarri

+0

Merci beaucoup votre sbi :) – Robin

+0

@Falmarri: Vous avez un point très valable là-bas. – sbi

2

Vous pouvez "surcharge" l'opérateur [], essayez:

struct e { 
    std::string content; 
    std::string name; 
    std::map<std::string, std::vector<e> > elements; 
    std::vector<e>& operator [](const std::string& s); 
}; 

... 

std::vector<e>& e::operator [](const std::string& s) { 
    return elements[s]; 
} 
+0

Oui à droite, j'ai fait des changements en conséquence :) – tauran

+1

En C++ il n'y a absolument pas besoin de 'typedef struct e {...} e;' - c'était seulement nécessaire dans C. –

+0

Vraiment? C'est bien, je ne le savais pas ... – tauran

1

Vous n'avez pas besoin de modèles. Vous avez simplement besoin d'un operator[]:

std::vector<e>& e::operator[](std::string const& s) { return this->elements[s]; } 
// elements.operator[s] inserts s if it doesn't exist yet. That's non-const so the following won't work 
// std::vector<e> const& e::operator[](std::string const& s) const { return this->elements[s]; } 
+0

La version 'const' devrait être beaucoup plus élaborée que celle de' std :: map'. En outre, en l'implémentant, vous serez confronté au même problème qui conduit à 'std :: map' sans avoir une surcharge' const' de 'operator []()'. Et vous devez améliorer votre chuchotis. ':)' – sbi

+0

ofc, expliqué. – MSalters

+0

1) Vous n'avez pas attribué votre réponse de commentaire et je suis seulement venu ici accidentellement. 2) Je ne sais pas ce que "ofc" signifie. – sbi