2009-06-30 14 views

risposta

22

Beh, dipende da come si desidera visualizzare loro, ma è sempre possibile scorrere facilmente:

typedef map<string, list<string>>::const_iterator MapIterator; 
for (MapIterator iter = mapex.begin(); iter != mapex.end(); iter++) 
{ 
    cout << "Key: " << iter->first << endl << "Values:" << endl; 
    typedef list<string>::const_iterator ListIterator; 
    for (ListIterator list_iter = iter->second.begin(); list_iter != iter->second.end(); list_iter++) 
     cout << " " << *list_iter << endl; 
} 
+0

perché post-incremento? – triclosan

+0

@triclosan: puoi anche pre-incrementare, non importa in questo caso. O ti ho frainteso? – Skurmedel

+0

utilizzo di guadagni post-incremento per la creazione di oggetti temporanei extra – triclosan

10

mi piacerebbe provare il seguente

void dump_list(const std::list<string>& l) { 
    for (std::list<string>::const_iterator it = l.begin(); l != l.end(); l++) { 
    cout << *l << endl; 
    } 
} 

void dump_map(const std::map<string, std::list<string>>& map) { 
    for (std::map<string,std::list<string>>::const_iterator it = map.begin(); it != map.end(); it++) { 
    cout << "Key: " << it->first << endl; 
    cout << "Values" << endl; 
    dump_list(it->second); 
} 
+0

Ottenuto 'id non specificato prima di' <'token' nella prima riga: 'void dump_list (const std :: list & l) {'. Devo includere qualcosa? –

+0

In dump_list dovrebbe essere: std :: vector :: const_iterator it = l.begin(); for (it; it! = L.end(); ++ it) { std :: cout << * it << std :: endl; } e non l nel cout! Altrimenti è stato molto utile per me /Grazie! – Kahin

4

sono un po 'fuori tema qui ...

Immagino di voler scaricare il contenuto della mappa per il debug. Mi piace ricordare che la prossima versione di gdb (versione 7.0) avrà un interprete python integrato che sarà usato da gcc libstdC++ per fornire stampanti stl pretty. Ecco un esempio per il vostro caso

#include <map> 
    #include <map> 
    #include <list> 
    #include <string> 

    using namespace std; 

    int main() 
    { 
    typedef map<string, list<string> > map_type; 
    map_type mymap; 

    list<string> mylist; 
    mylist.push_back("item 1"); 
    mylist.push_back("item 2"); 
    mymap["foo"] = mylist; 
    mymap["bar"] = mylist; 

    return 0; // stopped here 
    } 

che si traduce in

(gdb) print mymap 
$1 = std::map with 2 elements = { 
    ["bar"] = std::list = { 
    [0] = "item 1", 
    [1] = "item 2" 
    }, 
    ["foo"] = std::list = { 
    [0] = "item 1", 
    [1] = "item 2" 
    } 
} 

Yay!

2

Un'altra forma, utilizzando <algorithm>:

void printPair(const pair<string, list<string> > &p) 
{ 
    cout << "Key: " << p.first << endl; 
    copy(p.second.begin(), p.second.end(), ostream_iterator<string>(cout, "\n")); 
}  
for_each(mapex.begin(), mapex.end(), printPair); 

programma di test:

#include <iostream> 
#include <map> 
#include <list> 
#include <iterator> 
#include <algorithm> 
using namespace std; 

void printPair(const pair<string, list<string> > &p) 
{ 
    cout << "Key: " << p.first << endl; 
    copy(p.second.begin(), p.second.end(), ostream_iterator<string>(cout, "\n")); 
} 

int main() 
{ 
    map<string, list<string> > mapex; 

    list<string> mylist1; 
    mylist1.push_back("item 1"); 
    mylist1.push_back("item 2"); 
    mapex["foo"] = mylist1; 
    list<string> mylist2; 
    mylist2.push_back("item 3"); 
    mylist2.push_back("item 4"); 
    mylist2.push_back("item 5"); 
    mapex["bar"] = mylist2; 

    for_each(mapex.begin(), mapex.end(), printPair); 
} 
27

Update (Ritorno al futuro): con C++ 11 gamma-based per i loop -

std::map<Key, Value> m { ... /* initialize it */ ... }; 

for (const auto &p : m) { 
    std::cout << "m[" << p.first << "] = " << p.second << '\n'; 
} 
0

È possibile scrivere una funzione sovraccaricata piuttosto generica, valida per due scopi:

  1. Funziona con qualsiasi map.
  2. Consente di utilizzare <<.

La funzione è

template<class key_t, class value_t> 
ostream& operator<<(ostream& os, const map<key_t, value_t>& m) { 
    for (typename map<key_t, value_t>::const_iterator it = m.begin(); 
      it != m.end(); it++) { 
     os << "Key: " << it->first << ", Value: " << it->second; 
    } 
    return os; 
} 

cout << funziona con qualsiasi map che << è definito per typename s key_t e value_t. Nel tuo caso, questo non è definito per value_t (= list<string>), quindi devi definirlo. In uno spirito simile, è possibile utilizzare

template<class T> 
ostream& operator<<(ostream& os, const list<T>& l) { 
    for (typename list<T>::const_iterator it = l.begin(); it != l.end(); it++) { 
     os << "\"" << *it << "\", "; 
    } 
    return os; 
} 

così, si può:

  1. Aggiungere queste due funzioni.
  2. Aggiungere i prototipi dove necessario.
  3. Utilizzare using namespace std; (o aggiungere std:: secondo necessità).
  4. Uso, ad es.,
    cout << mapex << endl;
    cout << li << endl;

Ricordate che se c'è qualche altro valido candidato per le << s appena definito (che prendo non c'è, altrimenti non chiedereste probabilmente questa domanda), si può avere la precedenza sopra quelli attuali.

Problemi correlati