2014-03-29 37 views
2

在這裏我的代碼。我想從vector中移除所有成功調用方法'release'的元素。std :: remove_if無法正常工作

bool foo::release() 
{ 
    return true; 
} 

// ... 
vector<foo> vec; 
// ... 
remove_if(vec.begin(), vec.end(), [](foo & f) { return f.release() == true; }); 
// ... 

remove_if不是從vector vec刪除所有元素。 remove_if如何工作?

回答

9

std::remove_if重新排列載體,使得你想保留的元素的範圍是[vec.begin(), return_iterator)(注意是部分開放範圍)的元素。所以你需要調用std::vector::erase來確保向量只包含所需的元素。這就是所謂的erase-remove idiom

auto it = remove_if(vec.begin(), 
        vec.end(), 
        [](foo & f) { return f.release() == true; }); 

vec.erase(it, vec.end()); 

在這裏,我把它分成兩行爲清楚起見,但它常常被看作是一個班輪。

+0

謝謝,它的工作原理,看起來還不錯。 – Slinner

0

由於remove_if算法對一系列由兩個前向迭代表示元素的操作時,它沒有底層的容器或收集的知識。

因此,沒有元素實際上從容器中取出。相反,所有不符合刪除標準的元素都會以相同的相對順序彙集到範圍的前面。

的其餘元件被留在一個有效的,但是未指定,狀態。完成後,remove會返回一個指向最後一個未移除元素的迭代器。

爲了實際消除容器中的元素,刪除應該與容器的erase成員函數結合使用(因此名稱爲「erase-remove idiom」)。

0

std::removestd::remove_if實際上並沒有刪除任何內容,只是給了你一個迭代器,然後你可以使用你使用的任何容器的相應成員函數擦除元素。在std::vector的情況下,erase

我請你讀斯科特邁爾斯這老文章:"My Most Important C++ Aha! Moments...Ever"

正是因此具有相當的衝擊和背叛的感覺,我發現,將刪除到容器永遠不會改變的元素個數在容器中,即使你要求它去除一切。舞弊!欺騙!虛假廣告!

0

http://en.wikipedia.org/wiki/Erase-remove_idiom

std::remove_if實際上並不 刪除的元素。它所做的是將滿足條件的元素移動到範圍的末尾。然後它將一個迭代器返回到被刪除的元素(實際上只是被移動)。這是在你身上,然後從容器中刪除該範圍。

vector<foo> vec; 
auto remove_start = remove_if(vec.begin(), vec.end(), [](foo & f) { return f.release() == true; }); 

vec.erase(remove_start, vec.end()); 

vec.erase(remove_if(vec.begin(), vec.end(), 
        [](foo & f) { return f.release() == true; }), 
      vec.end());