2010-06-05 5 views
3

Je me demandais s'il était possible de créer une structure contenant un certain nombre de variables et une carte dans une carte.Struct contenant une carte dans une carte? (C++/STL)

Ce que j'ai en ce moment:

typedef std::map<std::string,double> lawVariables; 

struct ObjectCustomData { 
    std::string objectType;  
    bool global_lock; 
    std::map<std::string, lawVariables> lawData; 
}; 

Ce struct est ensuite transmis à une autre fonction comme un seul bloc de données pour cet objet.

La configuration de la structure est la suivante: Chaque objet dispose d'un bloc de données qui contient: son TypeObjet, un bool pour une serrure, et un nombre variable de « lois » qui pourrait ressembler à ceci:

law1 -> var_a = 39.3; 
    -> var_g = 8.1; 
law8 -> var_r = 83.1; 
    -> var_y = 913.3; 
    -> var_a = 9.81; 

Premièrement, je ne sais pas si je devrais utiliser une carte dans une carte et deuxièmement, même si cela est valide, je ne sais pas comment le remplir avec des données et comment le rappeler par la suite. J'ai regardé des cartes parce que je peux alors rechercher (sur un nom) si un certain objet a une certaine loi, et si cette loi a certaines variables.

(désolé pour la première apparition post-désordre, espérons que cela est mieux :))

Répondre

2

I was wondering if it was possible to create a struct containing a number of variables and a map in a map

Oui. Il est possible d'avoir Map comme valeur dans une autre carte.

Si vous êtes particulier sur l'ordre d'insertion et les entrées sont moins pour carte intérieure, votre structure de données peut ressemble:

typedef std::vector<std::pair<std::string,double> > lawVariables; 

struct ObjectCustomData { 
    std::string objectType;  
    bool global_lock; 
    std::map<std::string, lawVariables> lawData; 
}; 

EDIT: J'ai vu votre modifier maintenant. Si la recherche est votre principale exigence, optez pour la carte.

Exemple:

typedef std::map<std::string,double> lawVariables; 

    struct ObjectCustomData { 
     std::string objectType;  
     bool global_lock; 
     std::map<std::string, lawVariables> lawData; 
    }; 

void test(ObjectCustomData& data) 
{ 
    lawVariables& variable = data.lawData["law_1"]; 
    variable["var_a"] = 39.3; 

} 
+1

@aJ - Lorsque j'essaie de compiler votre méthode de test, j'obtiens "error: no match for 'operator []' dans 'data [" law_1 "]'. Est-ce qu'il compile pour vous? J'utilise le compilateur g ++ en cygwin – dcp

+1

désolé.La première ligne aurait dû être data.lawData ["law_1"]; pls se référer à mon édition –

+0

Merci beaucoup pour les réponses, tous les deux!: D – Karrok

1

Ce que vous avez devrait fonctionner. Vous pouvez charger les données comme ceci:

ObjectCustomData data; 
    data.lawData["law_1"]["var_a"] = 39.3; 
    data.lawData["law_1"]["var_g"] = 8.1; 
    data.lawData["law_8"]["var_r"] = 83.1; 
    . 
    . 
    . 

Vous pouvez vérifier l'existence d'éléments comme celui-ci:

if (!data.lawData.count("law_x")) { 
    cout<<"law_x not found"<<endl; 
    } 

    if (data.lawData.count("law_1")) { 
    cout<<"law_1 was found"<<endl; 
    } 
+0

Le code pour vérifier l'existence des éléments est mauvais Si la clé "law_x" n'existe pas, créez-la (créez une carte vierge), puis interrogez sa taille, c'est-à-dire l'allocation pour la chaîne, la construction de la carte et ainsi de suite Vous êtes mieux d'utiliser std :: map :: find – utnapistim

+0

@utnapistim - Bon point, merci pour votre commentaire. annonce de trouver car c'est un peu plus propre IMO. J'ai mis à jour ma réponse. – dcp

0

Il suffit d'ajouter les éléments suivants Incase quelqu'un pourrait être d'autre à sa recherche aswell: (note, certaines d'entre elles seront peut-être utilisé ou si, ne hésitez pas à me le faire savoir :))

en .h:

typedef std::map<std::string,double> lawVariables; 
typedef std::map<std::string,double>::iterator lawVars; 
struct ObjectCustomData { 
    std::string objectType; 
    bool global_lock; 
    std::map<std::string, lawVariables> lawData; 
}; 


template <typename K, typename V, class C, class A> 
std::ostream &operator<< (std::ostream &os, std::map<K,V,C,A> const& m) 
{ 
    os << "{ "; 
    typename std::map<K,V,C,A>::const_iterator p; 
    for (p = m.begin(); p != m.end(); ++p) { 
     os << p->first << ":" << p->second << ", "; 
    } 
    return os << "}"; 
} 

Remarque: le modèle vous permet de personnaliser simplement une carte dans la carte.

void setCustomData(); 
    void showCustomData(); 
    bool checkLaw(std::string law); 
    bool checkVar(std::string law,std::string var); 
    double getLawVar(std::string law, std::string var); 
    template<class T,class A> 
    void showMap(const std::map<T, A>& v); 
    ObjectCustomData ocd; 

Note: Le setCustomData sera remplit juste la carte en carte avec des données aléatoires pour des fins de test, showCustomData utilise simplement le modèle et l'opérateur personnalisé pour afficher la carte entière. CheckLaw et checkVar vérifient qu'une certaine valeur existe même et getLawVar renvoie la valeur d'un certain certain d'une certaine loi. showMap affiche tout le contenu de la carte dans une carte avec une sortie un peu plus agréable.

dans le.Je saute le setCustomData, c'est juste un tas de ocd.lawData [loi] [var] = 123.45; J'espère que c'est au moins un peu utile pour quelqu'un, n'hésitez pas à commenter sur ce que je pourrais/devrait faire mieux.

+1

Veuillez noter que toutes les chaînes et les cartes transmises par valeur dans ce code doivent être passées en tant que références const. En outre, vous devez étudier le concept de la fonction membre const. –

+0

Années de Java: Karrok

Questions connexes