Карта STL внутри карты С++
В С++-карте STL у меня есть определение типа
map<string, map<int, string> >;
и я итерации, используя следующий код.
for( map<string, map<int, string> >::iterator ii=info.begin(); ii!=info.end(); ++ii){
for(map<int, string>::iterator j=ii->second.begin(); j!=ii->second.end();++j){
cout << (*ii).first << " : " << (*j).first << " : "<< (*j).second << endl;
}
}
Мое сомнение в том, что это правильный способ повторения или есть лучший способ сделать это?
Вышеприведенный код работает для меня. Но m ищет более элегантное решение.
Ответы
Ответ 1
Это правильно, просто не хватает нескольких typedef
и улучшений читаемости:
typedef std::map<int, std::string> inner_map;
typedef std::map<std::string, inner_map> outer_map;
for (outer_map::iterator i = outerMap.begin(), iend = outerMap.end(); i != iend; ++i)
{
inner_map &innerMap = i->second;
for (inner_map::iterator j = innerMap.begin(), jend = innerMap.end(); j != jend; ++j)
{
/* ... */
}
}
Ответ 2
Если доступен С++ 11, вы можете использовать цикл for
:
for(auto &i: info) {
for(auto &j: i.second) {
/* */
}
}
Если доступен только С++ 11 auto
:
for( auto i=info.begin(); i!=info.end(); ++i) {
for( auto j=i->second.begin(); j!=i->second.end(); ++j) {
/* */
}
}
Если вы можете использовать BOOST, BOOST_FOREACH:
typedef std::map<int, std::string> inner_map;
typedef std::map<std::string, inner_map> outer_map;
outer_map outer;
BOOST_FOREACH(outer_map::value_type &outer_value, outer){
BOOST_FOREACH(inner_map::value_type &inner_value, outer_value->second){
/* use outer_value and inner_value as std::pair */
}
}
Ответ 3
Пока непонятно, какую проблему вы решаете, имея карту внутри карты, я не думаю, что есть лучший способ повторить все элементы без использования этих итераторов. Единственное, что вы можете сделать для улучшения чтения кода, - это использование typedefs в типах шаблонов.
Однако, не лучше ли определить ваш map
как
multimap <string, MyClass>
где MyClass
определяется как пара целых чисел и строка, а также метод toString() для сброса содержимого и т.д.?
Ответ 4
Если С++ 11 доступен, мы могли бы использовать stl-алгоритм for_each и лямбда-функций для получения элегантного решения
typedef map<int, string> INNERMAP;
typedef map<string, INNERMAP> OUTERMAP;
OUTERMAP theMapObject;
// populate the map object
//итерация объекта карты теперь
std::for_each(theMapObject.cbegin(), theMapObject.cend(),
[](const OUTERMAP::value_type& outerMapElement)
{
// process the outer map object
const INNERMAP& innerMapObject = outerMapElement.second;
std::for_each(innerMapObject.cbegin(), innerMapObject.cend(),
[](const INNERMAP::value_type& innermapElemen)
{
//process the inner map element
});
});
Ответ 5
Если вы хотите итерации по обеим картам, то наилучшим способом является то, как вы представляли. Теперь, если есть что-то конкретное, которое вы хотите сделать, вам может быть лучше использовать функцию из заголовка алгоритма.