[英]C++ map/set iterator not incrementable error while using multimap
与多图有关的“映射/集迭代器不可递增”错误。 我曾尝试使用Google搜索来寻找答案,但是答案并没有帮助我。 我假设问题是因为我的代码的第一部分执行了“ akcja”命令,该命令可能(但不必)删除多图的一个组件:
while ((c = getch()) != 27)
{
if (c == 'n')
{
typedef multimap<int, Organizm*>::iterator iterator;
for (int i = 10; i>= 0; i--)
{
std::pair<iterator, iterator> iterpair = kolejnoscRuchu.equal_range(i);
iterator it = iterpair.first;
for (; it != iterpair.second; ++it)
{
if(it->second->inicjatywa !=0)
{
it->second->akcja();
}
}
}
}
如果满足某些条件,则akcja()将触发删除该元素的命令:
void Swiat::usunOrganizm(Organizm *organizm)
{
this->organizmy[organizm->pozycja.x][organizm->pozycja.y] = NULL;
typedef multimap<int, Organizm*>::iterator iterator;
std::pair<iterator, iterator> iterpair2 = this->kolejnoscRuchu.equal_range(organizm->inicjatywa);
iterator it2 = iterpair2.first;
for (; it2 != iterpair2.second; ++it2)
{
if (it2->second == organizm)
{
cout << "usuwam " << it2->second->rysowanie() << endl;
kolejnoscRuchu.erase(it2);
delete organizm;
break;
}
}
}
我添加了一个“ cout <<” usuwam“ << it2-> second-> rysowanie()<< endl;” 部分以确认从我的多重地图中删除任何元素后是否发生错误。 我将不胜感激任何帮助
如果你在删除元素it2
,那么你就可以不再使用it2
。 增加它将不再可能。
您可以轻松地编写一个迭代循环,以允许删除循环控件本身:
iterator it = iterpair2.first;
while (it != iterpair.second)
{
iterator next_it = it;
++next_it;
/* it's possible for it to be deleted here */
it = next_it;
}
但是,如果在循环体中擦除next_it
,则上述操作将失败。 因此,如果您想变得更笼统,则需要进行显式比较:
while (it != iterpair.second)
{
iterator next_it = it;
++next_it;
/* ... */
if (some_condition)
{
/* Need to erase it_to_erase */
if (it_to_erase == next_it) ++next_it;
theMap.erase(it_to_erase);
}
/* ... */
it = next_it;
}
即使这样,也需要迭代的代码也是擦除元素的代码。 如果擦除代码不相关(例如,因为它在迭代中调用的函数中),则实际上没有解决方案可以立即擦除。
因此,在这种情况下,您需要实施某种形式的延迟擦除。 在OP中出现的特殊情况下,其中映射的mapped_type
是其值不能为null的指针,延迟擦除的一种简单形式是简单地将要擦除的元素的映射值设置为0。
在下面的简单的延迟擦除方案中,我假设外循环本身可以自由擦除元素。 也就是说,它不在迭代过程中调用的函数中。 为了简单起见,我使用了一些C + 11功能。
/* Outer loop */
for (auto it = myMap.begin(), end = myMap.end();; ++i) {
/* Erase any previously marked elements */
while (it != end && !it->second) it = myMap.erase(it);
if (it == end) break;
/* Do something with this element */
/* ... */
/* This function might "delete" arbitrary elements. See below */
secondProcess(myMap);
/* At this point, "it" might not be valid, so you would need to
check before trying to use it.
*/
}
这是内部功能:
void secondProcess(MapType& myMap) {
/* ... */
for (auto it2 = myMap.begin(), end = myMap.end(); it2 != end; ++it2) {
if (it2->second) { /* Make sure the element is not already marked */
/* ... */
/* Here we've decided to erase the element at "it2"
* The delete comes from the code in OP; it is only OK if the
* mapped value is the only pointer to the object it points to.
*/
delete it2->second;
it2->second = 0;
/* Since we don't actually erase it2, no other adjustment
* is needed
*/
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.