Loop C ++ através do Mapa

216

Eu quero percorrer cada elemento no map<string, int>sem conhecer nenhum dos seus valores ou chaves string-int.

O que tenho até agora:

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?  
       }
}
NoName
fonte
3
Possível duplicata Como loop através de um C ++ Roteiro
amanuel2

Respostas:

488

Você pode conseguir isso da seguinte maneira:

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 ;
}

Com o C ++ 11 (e em diante) ,

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

Com o C ++ 17 (e em diante) ,

for( auto const& [key, val] : symbolTable )
{
    std::cout << key         // string (key)
              << ':'  
              << val        // string's value
              << std::endl ;
}
P0W
fonte
7
adicionar o tipo de "auto" na frente de "it"
iedoc
2
@ P0W Por que "auto const &" para C ++ 11, mas "const auto" para C ++ 17? Alguma diferença entre "auto const &" e "const auto &"?
Eric
35
Não há diferença, é apenas uma questão de gosto. No entanto, parece que @ 's gosto P0W não é muito conistent ...
Kapichu
15
Obrigado por atualizar com o C ++ 17, eu estava procurando o auto const& [key, val] : symbolTableformato!
Água
3
@haram Você pode ter que set "ISO C ++ 17 Padrão (/ std: c ++ 17)" nas configurações do projeto (Configuração Propriedades> C / C ++> Idioma> C ++ Idioma Padrão)
Swordfish
27

Tente o seguinte

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

O mesmo pode ser escrito usando um loop for comum

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

Leve em consideração que value_type for std::mapé definido da seguinte maneira

typedef pair<const Key, T> value_type

Assim, no meu exemplo, p é uma referência const ao value_type em que Key é std::stringe T éint

Também seria melhor se a função fosse declarada como

void output( const map<string, int> &table );
Vlad de Moscou
fonte
14

O value_typede a mapé um paircontendo a chave e o valor como é firste secondmembro, respectivamente.

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

Ou com C ++ 11, usando o intervalo para:

for (auto const& p : symbolTable)
{
    std::cout << p.first << ' ' << p.second << '\n';
}
Columbo
fonte
7

Como o @Vlad de Moscou diz, leve em consideração que value_typepara std::mapestá definido da seguinte maneira:

typedef pair<const Key, T> value_type

Isso significa que, se você deseja substituir a palavra auto- chave por um especificador de tipo mais explícito, poderá fazê-lo;

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

Apenas para entender o que autoserá traduzido neste caso.

John Mutuma
fonte