2015-08-11 6 views
1

У меня есть двумерный карта, которую я объявленная так:C++ 11 - Range основы для петли на двухмерную карте

typedef std::map<std::string, std::map<std::string, Objective>> objectives_t; 

Я хочу, чтобы сохранить содержимое этой 2D-карты в файл.

Так что я пытался что-то вроде этого, вдохновленный какой-то код, который я нашел в Интернете:

for (auto const &subject : m_objectives) { 
    for (auto const &objective : m_objectives[subject.first]) { 
     //Print the objective 
    } 
} 

Но, конечно, это не работает. Как мне это сделать? Я не совсем уверен, что является предметом и объективностью (это некоторые итераторы?).

На второй строке, я получаю:

error: passing 'const objectives_t {aka const std::map<std::basic_string<char>, std::map<std::basic_string<char>, Objective> >}' as 'this' argument of 'std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = std::basic_string<char>; _Tp = std::map<std::basic_string<char>, Objective>; _Compare = std::less<std::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::basic_string<char>, std::map<std::basic_string<char>, Obj| 
+0

'для (авто const и цель: subject.second)' –

+1

Вы слишком глубоко выкопали. Сначала поймите простую «карту » и убедитесь, что вы можете писать циклы на основе диапазона, чтобы перебирать ее. –

+0

Возможно, проанализируйте синтаксис и семантику цикла, основанного на диапазонах, вместо того, чтобы опробовать случайный код. – juanchopanza

ответ

7

Ваш цикл Outter правильно. Но внутренний должен быть итерация subject.second

for (auto const &subject : m_objectives) { 
    for (auto const &objective : subject.second) { 
     // print out objective.second 
    } 
} 

Это происходит потому, что после первого диапазона на основе цикл, subject имеет тип

std::pair<const std::string, std::map<std::string, Objective>> const& 

Таким образом, каждый элемент

subject.first // std::string 
subject.second // std::map<std::string, Objective> 

Тогда, когда вы перебираете subject.second, ваш objective в настоящее время

std::pair<const std::string, Objective> const& 

Итак, еще раз, чтобы растащить элементы

objective.first // std::string 
objective.second // Objective 
+0

Он отлично работает для меня. Ткань. Но я не понимаю, почему моя версия не работает: m_objectives [subject.first] равно в subject.second no? – Bobog

+0

@Bobog Чтобы использовать вложенную карту, сначала вам нужно понять, как работает карта. – juanchopanza

+2

@Bobog да, но 1. вы уже выполнили работу, необходимую для определения ценности, нет смысла делать это дважды; 2. вы должны использовать 'map.at (key)' on 'const' maps, потому что' map [key] 'добавляет построенное по умолчанию значение, если ключ не существует и, следовательно, не является' 'constst''. – Quentin

0

m_objectives в приведенном выше коде const.

operator[] не работает на картах const, так как он определен для изменения карты, если ключ не найден.

Так вот в чем ваша ошибка. Обратите внимание, что если он каким-то образом изменил карту, внешний цикл был бы завинчен, поэтому карта была const luckate. Как вы заметили, на самом деле это не изменило бы его в этом случае (поскольку вы кормите его ключи от себя).

[] будет неэффективным, независимо от того, как он генерирует дополнительный поиск карты, когда у вас есть часть значения прямо там.

Исправление просто:

for (auto const &subject : m_objectives) { 
    for (auto const &objective : subject.second) { 
    //Print the objective 
    } 
} 

который и правильно (в том, что он не использует [] на const map) и быстрее (в том, что если вы незамедленный const -ified в mapm_objectives как-то , используя [], а итерация по карте неэффективна и подвержена ошибкам).

 Смежные вопросы

  • Нет связанных вопросов^_^