2013-07-26 39 views
0

我注意到vector::push_backinsert之間的行爲不同。std :: move在vector :: insert和push_back上的行爲不同

當我做

iter = myVector.begin() + 5; 
myVector.push_back(std::move(*iter)); 

在矢量第六元素被添加到了底部,並會從原來的位置刪除。

然而,如果我這樣做:

iterBegin = myVector.begin(); 
myVector.insert(iterBegin,std::move(*(iterBegin + 5))); 

第六元素被插入在第一的位置,但它沒有被刪除的形式以前的位置。

爲什麼std::moveinsert()中不起作用,如push_back()

+1

我在g ++上試過了,我沒有得到第6個元素被刪除。我甚至不明白爲什麼它應該被刪除......(儘管它可能會處於不可用狀態,但你永遠不應該「移動」,認爲你仍然在使用它)。你是如何檢查它被刪除的?第七個元素是否仍然存在? 「尺寸」是否改變了? – rabensky

+0

您可以添加一個完整的代碼示例,包括向量的聲明以及您檢查舊元素是否仍然存在的方式? – jogojapan

+0

據我所知,'std :: move'不會從容器中移除一個元素。最多它將竊取該元素的內容並將它們移動到一個新對象中,但舊元素的「外殼」仍將留在容器中。 –

回答

3

17.6.4.9函數自變量[res.on.arguments]/P1/B3表示:

1中的每個下面的適用於所有的參數定義在C++標準庫函數 ,除非明確地陳述除此以外。

...

  • 如果一個函數參數綁定到一個右值引用參數,實現可能會認爲這個參數是一個獨特的參考 這種說法。 [:如果所述參數是所述形式T&&A類型的左值被綁定的 通用參數,參數結合 到左值參考(14.8.2.1),從而不覆蓋由 前一句。 - 注完] [:如果程序蒙上了 左值到x值,同時通過該左值的庫函數 (例如,通過調用帶有參數move(x)功能),該 程序eectively問這個功能將該左值視爲 臨時值。如果參數是一個左值,則實現可以自由地優化掉可能需要的別名檢查 。 - 尾註]

總之,矢量假定由&&在兩個insertpush_back引用的參數是一個暫時的,因此確實沒有預防性混疊檢查。事實證明,假設你插入了一個左值,或者push_back了一個左值,那麼push_back算法無論如何都不需要檢查別名。然而,insert算法(我具體說vector,而不是其他容器)。所以當你使用move時,你不會注意到在push_back上缺少別名檢查,因爲它們無論如何都不會有所作爲。但是,您注意到insert上缺少這些內容。

1

迭代器只有在收集類(在本例中爲vector)未被修改時纔有效。一旦你第一次插入,你會使你的迭代器失效,結果是未定義的。

因此無論哪種情況下,iter變得無效,壞的事情會發生!或者更糟糕的是,它似乎工作除了發佈版本,或在一臺舊機器上,或月球已滿,等等。

而是,考慮複製要添加到新容器的元素,然後添加他們。

相關問題