2012-11-29 42 views
5

我有一些代码,我使用的gcc 4.7(从3.1)std :: multiset :: iterator = NULL不再有效吗?

更新到C++ 11 I有定义为类的私有成员一个多重集:

multiset <Object*, objectcomp> objects_; 

在代码是,是这样的一个部分(p_q是一对多集的迭代器,约那个讨厌的线抱歉,不能等待替换成自动,哈哈):

void Terrain::removeObject(Object* obj){ 
    pair<multiset<Object*, objectcomp>::iterator, multiset<Object*, objectcomp>::iterator> p_q; 
    multiset<Object*, objectcomp>::iterator p,q; 
    q = NULL; 
    p_q = objects_.equal_range(obj); 
    for(p = p_q.first; p != p_q.second; p++){ 
     if(*p == obj) {q=p; break;} 
    } 
    if(q!=NULL){ 
     ... do stuff based on q no longer being null 
    } 
} 

这将无法编译了。你不能将迭代器设置为null吗?什么是替代方案? (nullptr也不起作用)

+9

这是**从来没有**有效。 – ildjarn

+1

哦,那真是尴尬,哈哈 –

回答

7

将迭代器设置为NULL永远不合法。你可能很幸运,因为你的特定实现恰巧使用指针作为这种类型的迭代器,但它仍然是非法的。

正确的答案是:

q = objects_.end(); 

或者,在某些情况下:

q = multiset<Object*, objectcomp>::iterator(); 
+1

任何人都知道为什么我的第一个代码块没有显示为代码? – abarnert

+0

复制和粘贴不起作用...但删除'_',然后切割,然后粘贴,做...奇怪... – abarnert

+0

原来你有非破坏空间,而不是适当的空间;显然,SO不会将不间断空格计为缩进空格。 – ildjarn

2

你永远可以设置一个迭代为NULL。如果上述代码有效,那纯属意外。鉴于multiset的任何合理实现,很难看到它是如何编译的,更不用说运行了。

获得“无处”迭代器的最佳方式是使用容器的末尾。将q = NULL替换为q = objects_.end()

此外,永远不要将原始指针放在容器中;这是对内存泄漏的公开邀请。您几乎可以肯定需要multiset<Object,comp>multiset<shared_ptr<Object>,comp>

+0

我从来没有听说过shared_ptr我想我会看看。感谢**指针**。 –

+0

+1表示不使用容器中的原始指针。 @EricB:再看一下[boost :: ptr_container](http://www.boost.org/doc/libs/1_52_0/libs/ptr_container/doc/ptr_container.html),它可以让容器拥有尖端的,对象。如果对象在离开容器后不需要保持活动状态(或者只需要在当前范围结束时保持活动状态(如果它们已经离开容器),则可能会更简单(并且更高效)比共享指针的容器。 – abarnert