Ошибка времени выполнения: сопоставить / установить итераторы несовместимы - PullRequest
9 голосов
/ 22 сентября 2010

У меня во время выполнения ошибка "сопоставить / установить итераторы несовместимы" в строке 8.

void Manager::Simulate(Military* military, Shalishut* shalishut,char* args[]){
    Simulation* simulation = Simulation::GetInstance();
    Time* time = Time::GetInstance();

    multimap<int,Task*>::iterator itTasks;
    itTasks = simulation->GetTasks().begin();
    while(itTasks != simulation->GetTasks().end()){
      while (itTasks->second->GetTimeStamp() == time->GetTime()){ /*line 8 - ERROR*/
            TaskExecute(itTasks->second,military,shalishut,args);
            itTasks++;
        }
        // Unit take car of vehicles
        time->TimeIncrease();
    }

}

Simulation объявлено как multimap<int,Task*>.В чем проблема?

1 Ответ

18 голосов
/ 30 августа 2011

Я собираюсь сделать дикое предположение и сказать, что подпись Simulation::GetTasks() выглядит следующим образом:

multimap<int,Task*> GetTasks() const;

Это создает новую мультикарту ( копия ) каждый раз, когда вы вызываете ее.

При сравнении итераторов оба итератора multimap<int,Task*> должны быть из одного контейнера; так как вы получаете новую копию каждый раз, когда звоните GetTasks(), вы нарушаете это ограничение, и это является источником вашей ошибки. У вас также есть другая проблема - временные многокартовые копии уничтожаются после оператора, в котором они созданы, поэтому ваши итераторы мгновенно становятся недействительными.

У вас есть два варианта; Один из них заключается в том, чтобы получить копию локально и последовательно использовать эту копию:

multimap<int,Task*> tasks = simulation->GetTasks();
multimap<int,Task*>::iterator itTasks;
itTasks = tasks.begin();
while(itTasks != tasks.end()){
  while (itTasks->second->GetTimeStamp() == time->GetTime()){
        TaskExecute(itTasks->second,military,shalishut,args);
        itTasks++;
    }
    // Unit take car of vehicles
    time->TimeIncrease();
}

Другой способ - GetTasks() возвращать ссылку на постоянную мультикарту, гарантируя, что одна и та же используется каждый раз:

multimap<int,Task*> &GetTasks();

Или постоянная ссылка:

const multimap<int,Task*> &GetTasks() const;

Преимущество этого состоит в том, чтобы избежать (потенциально больших) накладных расходов при копировании multimap.

Обратите внимание, что использование константной ссылки требует использования const_iterator s для перехода по мультикарте. Я бы порекомендовал определить как константные, так и неконстантные методы доступа (C ++ выберет правильный, исходя из того, является ли указатель или ссылка Simulation постоянным), если только вы не хотите полностью запретить прямое изменение базового multimap, в этом случае Вы можете определить только вариант const.

...