Boucle C ++ via la carte

217

Je veux parcourir chaque élément du map<string, int>sans connaître ses valeurs ou clés string-int.

Ce que j'ai jusqu'à présent:

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?  
       }
}
Sans nom
la source
3
Copie

Réponses:

491

Vous pouvez y parvenir comme suit:

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

Avec C ++ 11 (et versions ultérieures) ,

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

Avec C ++ 17 (et versions ultérieures) ,

for( auto const& [key, val] : symbolTable )
{
    std::cout << key         // string (key)
              << ':'  
              << val        // string's value
              << std::endl ;
}
P0W
la source
7
ajouter le type "auto" devant "it"
iedoc
2
@ P0W Pourquoi "auto const &" pour C ++ 11 mais "const auto &" pour C ++ 17? Une différence entre "const auto &" et "const auto &"?
Eric
35
Il n'y a pas de différence, c'est juste une question de goût. Cependant, il semble que le goût de @ P0W ne soit pas très cohérent ...
Kapichu
15
Merci d'avoir mis à jour avec le C ++ 17, je cherchais le auto const& [key, val] : symbolTable format!
Water
3
@haram Vous devrez peut-être définir "Norme ISO C ++ 17 (/ std: c ++ 17)" dans les paramètres du projet (Propriétés de configuration> C / C ++> Langue> Norme de langage C ++)
Swordfish
27

Essayez ce qui suit

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

La même chose peut être écrite en utilisant une boucle for ordinaire

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

Tenez compte du fait que value_type for std::mapest défini de la manière suivante

typedef pair<const Key, T> value_type

Ainsi, dans mon exemple, p est une référence constante au value_type où Key est std::stringet T estint

Il serait également préférable que la fonction soit déclarée comme

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

Le value_typede a mapest un paircontenant la clé et la valeur comme il est firstet secondmembre, respectivement.

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

Ou avec C ++ 11, en utilisant une plage pour:

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

Comme le dit @Vlad de Moscou, tenez compte du fait que value_typefor std::mapest défini de la manière suivante:

typedef pair<const Key, T> value_type

Cela signifie alors que si vous souhaitez remplacer le mot-clé autopar un spécificateur de type plus explicite, vous pouvez le faire;

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

Juste pour comprendre ce qui autose traduira dans ce cas.

John Mutuma
la source