2012-11-29 41 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