2014-03-25 38 views
4

看來,我認爲std::copy_if將是非常有用的過濾容器:就地的std :: copy_if

std::vector<int> vec { 1, 2, 3, 4 }; 
auto itEnd = std::copy_if(vec.begin(), vec.end(), vec.begin(), 
          [](int i) { return i > 2; }); 
vec.resize(itEnd - vec.begin()); 

然而,std::copy_if被指定的輸入和輸出範圍可以不重疊。

是否有替代方案?

+6

'remove_if'不會很好地解決你的問題嗎? –

回答

20

copy_if主要用於將範圍複製到另一個範圍/容器I.e.通過設計,算法的本質是將滿足某些條件的元素複製到另一個(非重疊)範圍或新的容器中。

remove_if更適合您的需求;它正是按照您的期望過濾出來的。但是,它只能通過重寫來刪除元素;新老兩端之間的殘餘將是函數完成後不確定因素,需要使用erase手動刪除,就像這樣:

std::vector<int> vec { 1, 2, 3, 4 }; 
vec.erase(std::remove_if(std::begin(vec), 
         std::end(vec), 
         [](int i) { return i <= 2; }), 
      std::end(vec)); 

這是一個C++成語由名稱erase-remove去。


相反的copy_if,如果copy是你想要的東西,那麼你已經替代了重疊的範圍,即copy_backward;從the documentation

如果d_first是在[第一,最後),性病:: copy_backward必須使用 代替的std ::複製。

+3

您的最後一段不正確:每次刪除後都不會有所有元素的移位(這會導致O(n^2)性能)。性能將是線性的,與'copy_if'類似。 – interjay

+0

@Yakk該評論指的是舊版本的答案,我現在已經刪除了它。 –

+0

@ legends2k:該標準沒有要求執行,但它確實要求性能特徵。所以不,一個符合實現可能不會採取O(n^2)。 –