2011-08-01 7 views
1

J'ai une situation quelque peu particulière que je n'arrive pas à résoudre.Accéder à des éléments dans des cartes de cartes avec des vecteurs de pointeurs partagés

J'ai suivi de nombreux exemples d'utilisation de cartes de cartes mais le vecteur de pointeurs partagés semble me jeter un peu de côté.

Supposons que je donne les résultats suivants:

typedef boost::shared_ptr<RecCounts> RecCountsPtr; 
typedef std::vector<RecCountsPtr> RecCountsPtrVec; 
typedef std::map<std::string, RecCountsPtrVec> InnerActivityMap; 
typedef std::map< std::string, InnerActivityMap > ActivityMap; 

RecCounts est une structure simple.

Maintenant, je pense que j'ai compris comment remplir mon ActivityMap correctement.

RecCountsPtr recCountsPtr(new RecCounts()); 
config.actType = "M"; 
config.mapDate = "2010/07"; 

recCountsPtr->iHousehold = "50"; 
recCountsPtr->iZero = "150"; 

config.actMap[config.actType][config.mapDate].push_back(recCountsPtr); 

Oui? Je n'ai pas d'erreurs de compilation/exécution pour ça ... mais comme je n'ai pas compris comment accéder à tous les différents éléments de la carte, je ne peux pas le confirmer!

Ceci est la structure config:

struct Config 
{ 
    std::string actType; 
    std::string mapDate; 

    // Map 
    ActivityMap actMap; 
    InnerActivityMap innerActMap; 

    //Iterator 
    ActivityMap::iterator actMapIter; 
    InnerActivityMap::iterator innerActMapIter; 
}; 

Maintenant, supposons que je veux accéder à chaque élément du ActivityMap. Comment aurais-je les éléments suivants?

La carte externe Clé?

for (config.actMapIter= config.actMap.begin(); 
    config.actMapIter != config.actMap.end(); 
    ++config.actMapIter) 
    { 
     std::cout << "Outer Key = " 
        << (*config.actMapIter).first << std::endl; 
    } 

Cela semblait faire l'affaire.

La carte intérieure Clé? Je ne peux pas comprendre cela.

Les éléments de vecteur de carte interne?

je peux le faire comme ça si je sais que les deux clés:

config.actMap[config.actType][config.mapDate][0]->iHouehold 
config.actMap[config.actType][config.mapDate][0]->iZero 

... mais ne peut pas à comprendre comment itérer à travers eux. :(

C'est ce que je l'ai fait pour essayer de itérer tous les éléments

for (config.actMapIter= config.actMap.begin(); 
     config.actMapIter != config.actMap.end(); 
     ++config.actMapIter) 
    { 
     std::cout << "Outer Key = " << (*config.actMapIter).first << std::endl; 
     for (config.innerActMapIter = config.innerActMap.begin(); 
      config.innerActMapIter != config.innerActMap.end(); 
      ++config.innerActMapIter) 
     { 
      std::cout << "Inner Key = " 
         << (*config.innerActMapIter).first << std::endl; 
      for (size_t i = 0; 
       i < config.actMap[(*config.actMapIter).first] 
            [(*config.innerActMapIter).first].size(); 
       ++i) 
      { 
       std::cout << "iHousehold = " 
          << config.actMap[(*config.actMapIter).first] 
              [(*config.innerActMapIter).first] 
              [i]->iHousehold << std::endl; 

       std::cout << "iZero = " 
          << config.actMap[(*config.actMapIter).first] 
              [(*config.innerActMapIter).first] 
              [i]->iZero << std::endl; 
      } 
     } 
    } 

Je ne reçois pas d'erreur, mais je ne reçois que la touche d'impression externe à l'écran.

extérieur Key = M

Je soupçonne que quelque chose ne va pas avec mon iterator intérieur ... en ce qu'elle est pas associée au ActivityMap. Même si je ne me trompe pas, je ne sais pas comment faire une telle association.

Des suggestions?

RÉPONSE (grâce à crashmstr):

Voici une version verbeux de la réponse proposée par crashmstr.

for (config.actMapIter= config.actMap.begin(); 
    config.actMapIter != config.actMap.end(); 
    ++config.actMapIter) 
{ 
    std::cout << "Outer Key = " << (*config.actMapIter).first << std::endl; 

    InnerActivityMap innerActMap = (*config.actMapIter).second; 
    InnerActivityMap::iterator innerActMapIter; 

    for (innerActMapIter = innerActMap.begin(); 
     innerActMapIter != innerActMap.end(); 
     ++innerActMapIter) 
    { 
     std::cout << "Inner Key = " << (*innerActMapIter).first << std::endl; 
     for (size_t i = 0; 
      i < config.actMap[(*config.actMapIter).first][(*innerActMapIter).first].size(); 
      ++i) 
     { 
      std::cout << "iHousehold = " 
         << config.actMap[(*config.actMapIter).first] 
             [(*innerActMapIter).first] 
             [i]->iHousehold << std::endl; 

      std::cout << "iZero = " 
         << config.actMap[(*config.actMapIter).first] 
             [(*innerActMapIter).first] 
             [i]->iZero << std::endl; 
     } 
    } 
} 

Je reçois le texte suivant afficher à l'écran:

extérieur Key = M

intérieure Key = 2010/07

iHousehold = 50

iZero = 150

+0

Étant donné que votre structure de 'config' détient le type d'activité et la date carte, et vous utilisez ces touches comme à la carte extérieure et des cartes internes respectivement, il semble chaque' L'instance de configuration n'aura qu'une seule clé pour les cartes externes et internes. Alors pourquoi avez-vous besoin d'une 'std :: map'? Pourquoi 'Config' ne peut-il contenir une instance de' RecCountsPtrVec'? – Praetorian

+0

Désolé, c'est une version VASTLY simplifiée de ce que je travaille réellement avec. Ces deux valeurs vont changer et seront utilisées pour créer des entrées dans la carte (s). – Rico

Répondre

2

Lors de l'itération sur une carte, .first est la "clé" et .second est la donnée qui appartient à cette clé.

Donc dans votre cas:

for (config.actMapIter= config.actMap.begin(); 
    config.actMapIter != config.actMap.end(); 
    ++config.actMapIter) 
{ 
    std::cout << "Outer Key = " << (*config.actMapIter).first << std::endl; 
    //(*config.actMapIter).second is a std::map<std::string, RecCountsPtrVec> 
    //create a new for loop to iterate over .second 
} 
+0

Oui, je vois. Je vous remercie! Je vais éditer ma question pour montrer une version verbeuse de ce que vous avez dit ici. – Rico

+1

'config.actMapIter-> first' fonctionne aussi bien. Pas besoin d'utiliser le plus complexe '(* config.actMapIter) .first'. – Sjoerd

Questions connexes