C ++ Loop a través del mapa

216

Quiero iterar a través de cada elemento en el map<string, int>sin conocer ninguno de sus valores o claves string-int.

Lo que tengo hasta ahora:

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?  
       }
}
Sin nombre
fuente
3
Posible duplicado de Cómo recorrer un mapa de c ++
amanuel2

Respuestas:

491

Puede lograr esto de la siguiente manera:

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

Con C ++ 11 (y en adelante) ,

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

Con C ++ 17 (y en adelante) ,

for( auto const& [key, val] : symbolTable )
{
    std::cout << key         // string (key)
              << ':'  
              << val        // string's value
              << std::endl ;
}
P0W
fuente
77
agregue el tipo "auto" delante de "it"
iedoc
2
@ P0W ¿Por qué "auto const &" para C ++ 11 pero "const auto &" para C ++ 17? ¿Hay alguna diferencia entre "auto const &" y "const auto &"?
Eric
35
No hay diferencia, es solo cuestión de gustos. Sin embargo, parece que el gusto de @ P0W no es muy consistente ...
Kapichu
15
Gracias por actualizar con C ++ 17, ¡estaba buscando el auto const& [key, val] : symbolTableformato!
Agua
3
@haram Puede que tenga que configurar "ISO C ++ 17 Standard (/ std: c ++ 17)" en la configuración del proyecto (Propiedades de configuración> C / C ++> Idioma> C ++ Language Standard)
Swordfish
27

Intenta lo siguiente

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

Lo mismo se puede escribir usando un ciclo for ordinario

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

Tenga en cuenta que value_type para std::mapse define de la siguiente manera

typedef pair<const Key, T> value_type

Por lo tanto, en mi ejemplo, p es una referencia constante al valor_tipo donde Key es std::stringy T esint

También sería mejor si la función se declarara como

void output( const map<string, int> &table );
Vlad de Moscú
fuente
14

El value_typede a mapes un que paircontiene la clave y el valor como es firsty secondmiembro, respectivamente.

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

O con C ++ 11, utilizando un rango basado para:

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

Como dice @Vlad de Moscú, tenga en cuenta que value_typepara std::mapse define de la siguiente manera:

typedef pair<const Key, T> value_type

Esto significa que si desea reemplazar la palabra clave autocon un especificador de tipo más explícito, entonces podría hacerlo ;

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

Solo por entender a qué autose traducirá en este caso.

John Mutuma
fuente