本文介绍了保留一个有效的vector :: iterator after erase()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑:我有很多答案告诉我,我应该将删除分成另一个循环。也许我没有足够清楚,但我在最后一段说,我想找到一个解决方案。即保持当前的代码结构,但使用一些鲜为人知的C ++ fu来使它工作。

I have had a lot of answers telling me that I should separate the deletion into another loop. Perhaps I did not make it clear enough, but I stated in my last paragraph that I'd like to find a solution OTHER than that. ie keeping the current code structure, but using some little-known C++fu to make it work.

好吧,我知道调用 ()使向量的迭代器无效,并且它之后的所有那些,和 erase()返回一个迭代器到下一个有效的迭代器,

Well, I know that calling erase() on a vector invalidates iterators to the element and all those after it, and that erase() returns an iterator to the next valid iterator, but what if the erase happens elsewhere?

我有以下情况(简化):

I have the following situation (simplified):

警告:不要假设这是整个代码。下面显示的是极其简化以说明我的问题。下面显示的所有类和方法实际上要复杂得多。

WARNING: Do NOT assume that this is the entire code. What is shown below is EXTREMELY simplified to illustrate my problem. All the classes and methods shown below are actually far more complex.

class Child {
   Parent *parent;
}

class Parent {
   vector<Child*> child;
}

void Parent::erase(Child* a) {
   // find an iterator, it, that points to Child* a
   child.erase(it);
}

int Child::update() {
   if(x()) parent.erase(*this) // Sometimes it will; sometimes (most) it won't
   return y;
}

void Parent::update() {
   int i = 0;
   for(vector<A>::iterator it = child.begin(); it != child.end(); it++)
      i += (*it)->update();
}

因此,显然,它会在运行 (* it) - > update()如果 x()返回true,

So, obviously, it will crash after it runs (*it)->update() if x() returns true, because when it does, the Child will tell the Parent to remove it from the vector, invalidating the iterator.

有任何修复这个方法,除了 Parent :: erase()遍历迭代器返回 Parent :: update()?这将是有问题的,因为它不是每次调用 Child :: update()时调用,因此该函数将需要一种方法来为每个单元返回一个迭代器其他时间,并且它当前也返回另一个值。我也希望避免一些其他类似的方法来分离擦除过程和更新循环。

Is there any way of fixing this other than making Parent::erase() pass an iterator all the way back up to Parent::update()? This would be problematic, as it is not called for every call to Child::update(), and thus that function would need a way to return an iterator to itself every single other time, and it is also currently returning another value. I would also prefer to avoid some other similar way to separate the erasing the process from the updating loop.

推荐答案

除非在突变的迭代之间有一些通信。

You can't really iterate over and mutate a std::vector at the same time unless there's some communication between the iteration that the mutation.

我看过其他的,非标准的,容器通过智能迭代器来调度它们,知道它们的值何时被擦除(并且可能自动跳转到下一项)。这是一个非常多的书保留。

I've seen other, non-standard, containers facilatate this through "smart" iterators that know when their value has been erased (and maybe auto-jump to the next item). It's quite a bit more book-keeping though.

这篇关于保留一个有效的vector :: iterator after erase()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-27 20:13