迭代器失效问题 [英] iterator invalidation trouble

查看:69
本文介绍了迭代器失效问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述




我遇到一些众所周知的问题。迭代器失效。我的

情况:


for(it = v.begin(); it!= v.end(); ++ it){

f(* it);

}


在某些情况下,f可以通过删除当前的
$ b来改变容器$ b项目。因此迭代器无效。我的问题是,如果有办法

来处理这个具体案例。问题是for循环是用户

代码,用户甚至不应该注意到v发生了变化,所以我不能简单地在for循环中引入第二个迭代器。如果*它被删除,it / b $ b $迭代器应该继续使用以下项目。

*它绝对是唯一可以被f删除的项目。 br />
我认为这个问题比较笼统。

for c ++的强大迭代器在线是否有线程?我的情况有诀窍吗?


问候,

alex

解决方案

< blockquote> Alexander Stippler写道:



我遇到了一些众所周知的问题。迭代器失效。我的情况:

for(it = v.begin(); it!= v.end(); ++ it){
f(* it);
}

在某些情况下,f可能会删除当前的
项目来改变容器。因此迭代器无效。我的问题是,如果有办法处理这个具体案例。问题是for循环是用户代码,用户甚至不应该注意到v发生了变化,所以我不能简单地在for循环中引入第二个迭代器。如果*它被删除,it / it>应该继续迭代下面的项目。
*它绝对是唯一可以被f删除的项目。
我认为这个问题是相当一般。
针对c ++的强大迭代器在线是否有任何线程?我的情况有诀窍吗?




我过去解决这个问题的方法是不擦除物体。

我使容器有指向对象的指针,一旦用户完成迭代,它就会删除空。指针。


我还提供了一个traverser。在循环结束时使用

包装for循环的模板。




" Alexander Stippler" < ST ** @ mathematik.uni-ulm.de>在留言新闻中写道:3f ****** @ news.uni-ulm.de ...

我认为这个问题比较笼统。
针对c ++的强大迭代器在线是否有任何线程?我的情况有诀窍吗?




您说用户不应该知道容器是否已更改,但是

,因为您把他所有的丑陋暴露给他,他确实必须知道。


如果没有更好的

描述,很难理解建议的解决方案问题。当f()不在他们的控制范围内时,为什么用户负责

在列表上迭代一些函数f()。通过将

容器v(或开始和结束迭代器)传递给f()并让它(> b $ b)管理搜索列表本身,可以更好地解决这个问题。


Ron Natalie写道:


Alexander Stippler < ST ** @ mathematik.uni-ulm.de>在消息中写道
新闻:3f ****** @ news.uni-ulm.de ...

我认为这个问题比较笼统。
针对c ++的强大迭代器在线是否有任何线程?我的情况有诀窍吗?



你说用户不应该知道容器是否已经改变,但是因为你把所有的丑陋暴露给他,必须知道。

如果没有更好的问题描述,很难理解提出什么样的解决方案。当f()不在其控制之下时,为什么用户负责在列表上迭代某些函数f()。可能通过将
容器v(或开始和结束迭代器)传递给f()并让它管理对列表本身的搜索来更好地解决这个问题。



作为我的应用程序的一个例子,让v是一个算术稀疏向量,其中

我只想存储非零元素。现在我有了例如

operator-(SparseVector v,double c),它可以在内部有一个循环

,使用迭代器_it_将c添加到每个非零元素。这是

客户端代码 - 我不想考虑使用迭代器在每个函数中删除

元素的可能性。

如果c == * _it_,这将导致* _it_ == 0,因此删除了当前项目

。当分配* _it_它的新值

(通过代理)时,会立即发生这种情况。

就是这样。怎么办呢?我考虑过不立即删除* _it_,

但是我必须猜测正确的时间。有没有比使用容器注册迭代器更简单的解决方案?


问候,

alex


Hi,

I''ve got trouble with some well known issue. Iterator invalidation. My
situation:

for (it=v.begin(); it!=v.end(); ++it) {
f(*it);
}

Under some circumstances, f may alter the container by removing the current
item. Thus the iterator it gets invalid. My question is, if there is a way
to handle this specific case. The problem is that the for loop is user
code, and the user should not even notice that v changed, so I cannot
simply introduce a second iterator inside the for loop. The iterator it
should simply go on iterating with the following item, if *it is deleted.
*it is defininitely the only item which can be deleted by f.
I think this problem is rather general. Are there any threads online on
"robust iterators for c++"? Is there a trick for my situation?

regards,
alex

解决方案

Alexander Stippler wrote:

Hi,

I''ve got trouble with some well known issue. Iterator invalidation. My
situation:

for (it=v.begin(); it!=v.end(); ++it) {
f(*it);
}

Under some circumstances, f may alter the container by removing the current
item. Thus the iterator it gets invalid. My question is, if there is a way
to handle this specific case. The problem is that the for loop is user
code, and the user should not even notice that v changed, so I cannot
simply introduce a second iterator inside the for loop. The iterator it
should simply go on iterating with the following item, if *it is deleted.
*it is defininitely the only item which can be deleted by f.
I think this problem is rather general. Are there any threads online on
"robust iterators for c++"? Is there a trick for my situation?



The way I''ve solved this problem in the past is to not erase the objects.

I made the container have pointers to the objects and once the user was
done with the iterating it would erase the "empty" pointers.

I also provided a "traverser" template that would wrap the for loop with
the appropriate cleaning call at the end of the loop.



"Alexander Stippler" <st**@mathematik.uni-ulm.de> wrote in message news:3f******@news.uni-ulm.de...

I think this problem is rather general. Are there any threads online on
"robust iterators for c++"? Is there a trick for my situation?



You say the user shouldn''t know if the container has changed, however
since you expose all the ugliness to him, he does have to know.

It''s hard to understand what solution to propose without a better
description of the problem. Why is the user responsible for
iterating some function f() over a list when f() is not under
their control. Possibly this is better solved by passing the
container v (or begin and end iterators) to f() and letting it
manage searching over the list itself.


Ron Natalie wrote:


"Alexander Stippler" <st**@mathematik.uni-ulm.de> wrote in message
news:3f******@news.uni-ulm.de...

I think this problem is rather general. Are there any threads online on
"robust iterators for c++"? Is there a trick for my situation?



You say the user shouldn''t know if the container has changed, however
since you expose all the ugliness to him, he does have to know.

It''s hard to understand what solution to propose without a better
description of the problem. Why is the user responsible for
iterating some function f() over a list when f() is not under
their control. Possibly this is better solved by passing the
container v (or begin and end iterators) to f() and letting it
manage searching over the list itself.



As an example of my application, let v be an arithmetic sparse vector, where
I only want to store non zero elements. Now I have e.g.
operator-(SparseVector v, double c), which could internally have a loop
using an iterator _it_ to add c to every non-zero-element. Here is the
client code - I do not want to have to consider the possibility of deleting
elements in every function using an iterator.
If c == *_it_, this would result in *_it_ == 0 and thus the current item is
removed. This happens immediately, when assigning *_it_ its new value
(through a proxy).
That''s it. How to handle this? I considered not deleting *_it_ immediately,
but then I would have to guess the right time to do it. Is there any
simpler solution than registering iterators with their container?

regards,
alex


这篇关于迭代器失效问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆