RunTime错误:map / set迭代器不兼容

时间:2010-09-22 18:07:33

标签: c++ iterator runtime-error

我在第8行遇到了运行时错误“map / set iterators incompatible”。

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 个答案:

答案 0 :(得分:18)

我会猜测并说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引用:

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

这样做的好处是可以避免复制multimap的(可能很大)开销。

请注意,使用const引用需要使用const_iterator来逐步执行多重映射。我建议定义const和非const访问器(如果Simulation指针或引用是const,C ++将选择正确的访问器),除非你想要完全禁止直接修改底层multimap ,在这种情况下,您只能定义const变体。