2011-12-07 97 views
11

鑑於std::vector<std::unique_ptr<SomeType> >,對其使用 remove_if是否合法?換句話說,鑑於此代碼:你可以在`std :: unique_ptr`的容器上使用`std :: remove_if`嗎?

std::vector<std::unique_ptr<SomeType> > v; 
// fill v, all entries point to a valid instance of SomeType... 
v.erase(std::remove_if(v.begin(), v.end(), someCondition), v.end()); 

,我會擦除所有的指針還在v是 有效後保證。我知道,考慮到直觀實現 std::remove_if,並給予我所看到的所有實現, 他們將。我想知道是否有任何標準 保證它;即std::remove_if不允許複製 任何有效條目而不將該副本重新複製到其最終的 位置。

(我是,當然,假設條件不復制如果 條件具有類似特徵:

struct Condition 
{ 
    bool operator()(std::unique_ptr<SomeType> ptr) const; 
}; 

,那麼當然,所有的指針將是 後無效remove_if

+7

James Kanze提出問題 - 一個非常罕見的現象! – Nawaz

+3

'unique_ptr'不是可複製的,所以如果你使用了這個謂詞,你的代碼就不會編譯。 – interjay

+1

爲什麼不呢? 'std :: unique'不可複製,但可移動。它可以移動到容器的末端。 –

回答

2

25.3.8在N3290談到刪除功能:

要求:類型的第一*應滿足MoveAssignable 要求(表22)。

注:在範圍[RET每個元素,最後一個),其中,RET的返回 值,具有有效的但unspeci音響ED狀態下,由於算法可以 消除通過交換元件與原來在該範圍內的元素相關或從其中移出 。

這意味着它取決於你的謂詞操作符。由於您的謂詞不會創建副本,因此這些元素不會被複制。

+0

§25.3.8/ 1是對目標類型的約束,而不是對'remove'的 實現。第25.3.8/6是我正在尋找的。太 不好,這是一個說明,而不是規範。但它的確意圖清楚。 我應該在 之前閱讀筆記,而不僅僅是規範文本。 +1無論如何,如果沒有人發現更確切的東西,我會認爲這是最終的迴應。 –

+0

我有n3242。之後是否增加了§25.3.8/ 6?我的/ 6討論了'remove_copy [_if]'。 – kennytm

+2

我相信這個筆記是不正確的。好的事情是不規範的。 ;-)算法不允許交換元素,因爲元素不需要是可交換的。該算法只能使用移動分配。 –

5

就像erase()resize()remove_if()移動元素(可能通過交換),使容器中的元素並不需要可拷貝。 unique_ptr沒有什麼特別之處,它只是另一種移動類型。

正如你指出的那樣,謂詞當然應該由const-reference引用元素。再次,就像任何可移動的類型一樣。

+0

標準中規定了哪些內容?更重要的是,它在哪裏 指出'remove_if'不會移動到一些臨時的,也許以後到 將值留在那裏,因爲它確定不需要在其他地方放置 ?容器和成員函數已被重新編寫爲 以反映移動語義,但我不知道在這方面描述'remove_if'的語言 有任何更改。 –

+1

@JamesKanze:§25.3.8/ 1? – kennytm

+0

@KennyTM:擊敗我吧,謝謝! –

相關問題