2013-02-10 43 views
1

我有2個std ::列表。我想刪除列表1中的所有項目並將其插入到第二個項目中,反之亦然。我的代碼無法正常工作(獲得訪問衝突和「列表迭代器不dereferencable」)的第二個方法列表迭代器擦除「調試斷言失敗」

for (std::list<Item *>::iterator it = list1.begin(); it != list1.end(); ++it) { 
     it = list1.erase(it); 
     list2.push_back(*it); 
    } 
it = list1.begin(); 
it = list2.erase(it); // because the last element is not deleted in the above loop 
list2.push_back(*it); 

對稱碼。我設法在兩個列表之間轉移項目一次,但接下來我得到錯誤。

任何幫助?

+0

'std :: swap(list1,list2)'? – Johnsyweb 2013-02-10 23:33:43

+1

@Johnsyweb'std :: list :: swap'成員函數保證是恆定時間。它應該只涉及交換兩個指針(可能是C++ 11中的一個大小數據成員)。 – juanchopanza 2013-02-10 23:40:08

+0

@juanchopanza:那肯定會更好。 std :: swap'函數仍然會執行比提供的實現更好:) – Johnsyweb 2013-02-10 23:43:39

回答

3

這是很容易和有效地與std::listswap成員函數完成:

list1.swap(list2); 

這具有恆定時間複雜度。

+1

輕鬆獲得最快,最好的答案。 – skypower 2013-02-10 23:42:33

+0

@skypower然後你可以用綠色的勾號來接受它。 – Csq 2013-02-10 23:48:38

0

當然,你必須使用list::swap。 但是你的代碼顯示你有一些誤解。

for (std::list<Item *>::iterator it = list1.begin(); it != list1.end(); ++it) { 
    it = list1.erase(it); // this effectively erase and destroy *it, 
       // and erase() return an iterator to the NEXT element. 
       // Now it=it+1 
    list2.push_back(*it); // you copy the NEXT element!! 
    // here is where we efectively get the ++it of the 'for'. 
    // When erase was used when ‘it’ was at end()-1, erase return end() 
    // The attempt to do it=end()+1 is an error probably detected by an assertion. 
} 

如果list1有元素的最初偶數,例如0,1,2,3,4,5,6,7,8,9迭代end()將指向不存在10,你不要不需要(不能)清除。這'for'將刪除偶數元素(0,2,4,6,8),並複製到list2奇數(1,3,5,7,9)。但如果最初list1有奇數元素,例如0,1,2,3,4,5,6,7,8最後刪除的是8,erase返回一個迭代器到不存在的9 = end(),和'for'構成一個試圖增加它,但不要通過斷言。