C ++ Pętla przez mapę

216

Chcę iterować po każdym elemencie, map<string, int>nie znając żadnej z jego wartości string-int ani kluczy.

Co mam do tej pory:

void output(map<string, int> table)
{
       map<string, int>::iterator it;
       for (it = table.begin(); it != table.end(); it++)
       {
            //How do I access each element?  
       }
}
Bez nazwy
źródło
3
Możliwy duplikat „ Jak przejść przez mapę c ++”
amanuel2 26.04.16

Odpowiedzi:

490

Możesz to osiągnąć w następujący sposób:

map<string, int>::iterator it;

for ( it = symbolTable.begin(); it != symbolTable.end(); it++ )
{
    std::cout << it->first  // string (key)
              << ':'
              << it->second   // string's value 
              << std::endl ;
}

Z C ++ 11 (i nowszymi) ,

for (auto const& x : symbolTable)
{
    std::cout << x.first  // string (key)
              << ':' 
              << x.second // string's value 
              << std::endl ;
}

Z C ++ 17 (i nowszymi) ,

for( auto const& [key, val] : symbolTable )
{
    std::cout << key         // string (key)
              << ':'  
              << val        // string's value
              << std::endl ;
}
P0W
źródło
7
dodaj „auto” przed „it”
iedoc
2
@ P0W Dlaczego „auto const &” dla C ++ 11, a „const auto &” dla C ++ 17? Czy jest jakaś różnica między „auto const &” a „const auto &”?
Eric
35
Nie ma różnicy, to tylko kwestia gustu. Wydaje się jednak, że smak @ P0W nie jest zbyt
konsekwentny
15
Dzięki za aktualizację do wersji C ++ 17, szukałem auto const& [key, val] : symbolTableformatu!
Woda
3
@haram Być może trzeba ustawić „ISO C ++ 17 Standard (/ std: c ++ 17)” w ustawieniach projektu (Właściwości konfiguracji> C / C ++> Język> C ++ Language Standard)
Swordfish
27

Spróbuj wykonać następujące czynności

for ( const auto &p : table )
{
   std::cout << p.first << '\t' << p.second << std::endl;
} 

To samo można zapisać za pomocą zwykłej pętli for

for ( auto it = table.begin(); it != table.end(); ++it  )
{
   std::cout << it->first << '\t' << it->second << std::endl;
} 

Weź pod uwagę, że typ wartości dla std::mapjest definiowany w następujący sposób

typedef pair<const Key, T> value_type

Zatem w moim przykładzie p jest stałą odniesieniem do typu wartość, gdzie kluczem jest, std::stringa T jestint

Byłoby również lepiej, gdyby funkcja została zadeklarowana jako

void output( const map<string, int> &table );
Vlad z Moskwy
źródło
14

value_typeTematyce mapjest pairzawierający klucz i wartość, jak to firsti secondodpowiednio członka,.

map<string, int>::iterator it;
for (it = symbolTable.begin(); it != symbolTable.end(); it++)
{
    std::cout << it->first << ' ' << it->second << '\n';
}

Lub z C ++ 11, używając opartego na zakresie dla:

for (auto const& p : symbolTable)
{
    std::cout << p.first << ' ' << p.second << '\n';
}
Columbo
źródło
7

Jak mówi @Vlad z Moskwy, weź pod uwagę, że value_typedla std::mapjest zdefiniowany w następujący sposób:

typedef pair<const Key, T> value_type

Oznacza to, że jeśli chcesz zastąpić słowo kluczowe autobardziej precyzyjnym specyfikatorem typu, możesz to zrobić;

for ( const pair<const string, int> &p : table ) {
   std::cout << p.first << '\t' << p.second << std::endl;
} 

Tylko dla zrozumienia, co autow tym przypadku przełoży się na.

John Mutuma
źródło