Como percorrer um mapa de mapas em C ++?

Como eu faria um loop através de um std::map em C ++? Meu mapa é definido como:

 std::map< std::string, std::map > 

Por exemplo, isso contém dados como este:

 m["name1"]["value1"] = "data1"; m["name1"]["value2"] = "data2"; m["name2"]["value1"] = "data1"; m["name2"]["value2"] = "data2"; m["name3"]["value1"] = "data1"; m["name3"]["value2"] = "data2"; 

Como posso percorrer este mapa e acessar os vários valores?

Pergunta antiga, mas as respostas restantes estão desatualizadas a partir do C ++ 11 – você pode usar um loop for baseado em ranged e simplesmente fazer:

 std::map> mymap; for(auto const &ent1 : mymap) { // ent1.first is the first key for(auto const &ent2 : ent1.second) { // ent2.first is the second key // ent2.second is the data } } 

isso deve ser muito mais limpo do que as versões anteriores e evita cópias desnecessárias.

Alguns favorecem a substituição dos comentários por definições explícitas de variables ​​de referência (que são otimizadas se não utilizadas):

 for(auto const &ent1 : mymap) { auto const &outer_key = ent1.first; auto const &inner_map = ent1.second; for(auto const &ent2 : inner_map) { auto const &inner_key = ent2.first; auto const &inner_value = ent2.second; } } 

Você pode usar um iterador.

 typedef std::map>::iterator it_type; for(it_type iterator = m.begin(); iterator != m.end(); iterator++) { // iterator->first = key // iterator->second = value // Repeat if you also want to iterate through the second map. } 
 for(std::map >::iterator outer_iter=map.begin(); outer_iter!=map.end(); ++outer_iter) { for(std::map::iterator inner_iter=outer_iter->second.begin(); inner_iter!=outer_iter->second.end(); ++inner_iter) { std::cout << inner_iter->second << std::endl; } } 

ou melhor em C ++ 0x:

 for(auto outer_iter=map.begin(); outer_iter!=map.end(); ++outer_iter) { for(auto inner_iter=outer_iter->second.begin(); inner_iter!=outer_iter->second.end(); ++inner_iter) { std::cout << inner_iter->second << std::endl; } } 

Faça algo assim:

 typedef std::map InnerMap; typedef std::map OuterMap; Outermap mm; ...//set the initial values for (OuterMap::iterator i = mm.begin(); i != mm.end(); ++i) { InnerMap &im = i->second; for (InnerMap::iterator ii = im.begin(); ii != im.end(); ++ii) { std::cout << "map[" << i->first << "][" << ii->first << "] =" << ii->second << '\n'; } } 

Em C ++ 17, você poderá usar o recurso “ligações estruturadas”, que permite definir várias variables, com nomes diferentes, usando uma única tupla / par. Exemplo:

 for (const auto& [name, description] : planet_descriptions) { std::cout << "Planet " << name << ":\n" << description << "\n\n"; } 

A proposta original (pelos luminares Bjarne Stroustrup, Herb Sutter e Gabriel Dos Reis) é divertida de ler (e a syntax sugerida é mais intuitiva); Há também o texto proposto para o padrão que é chato de ler, mas está mais perto do que realmente vai entrar.

C ++ 11:

 std::map< std::string, std::map > m; m["name1"]["value1"] = "data1"; m["name1"]["value2"] = "data2"; m["name2"]["value1"] = "data1"; m["name2"]["value2"] = "data2"; m["name3"]["value1"] = "data1"; m["name3"]["value2"] = "data2"; for (auto i : m) for (auto j : i.second) cout << i.first.c_str() << ":" << j.first.c_str() << ":" << j.second.c_str() << endl; 

saída:

 name1:value1:data1 name1:value2:data2 name2:value1:data1 name2:value2:data2 name3:value1:data1 name3:value2:data2 

use std::map< std::string, std::map >::const_iterator quando map é const.