2010-06-29 63 views
1

推動有條件刪除我想要做的事,如C#LINQ風格:C++從容器

SomeColection <SomeType> someColection; 
someColection.Remove(something => something > 2); 

,它會清除所有那些更大然後2的東西(或任何其他布爾條件)...

在項目中使用提升...

回答

4

首先更換bind2nd的東西,你需要一個簡單的模板包裝:

template <class Container, class UnaryPredicate> 
void erase_if(Container& container, UnaryPredicate pred) 
{ 
    container.erase(
    std::remove_if(container.begin(), container.end(), pred), 
    container.end() 
); 
} 

這是一個衆所周知的成語,但mapset因爲他們維護他們自己的訂單將不可能。

然後,您可以使用Boost.Lambda來獲取您希望編寫謂詞本身的語法。

using boost::lambda::_1; 

SomeCollection<Type> someCollection; 

erase_if(someCollection, _1 > 2); 
+0

爲lambda表達式 – 2010-06-29 09:26:29

5

您不需要提升(除非您的主要焦點是內聯匿名函數)。 Plain STL很好。

#include <vector> 
#include <algorithm> 
#include <functional> 
#include <iostream> 

int main() { 
     std::vector<int> x (24); 
     for (int i = 0; i < x.size(); ++ i) 
       x[i] = i % 5; 

     std::vector<int>::iterator 
      new_end = std::remove_if(x.begin(), x.end(), 
            std::bind2nd(std::greater<int>(), 2)); 
     x.erase(new_end, x.end()); 

     for (int i = 0; i < x.size(); ++ i) 
       std::cout << x[i] << " "; 

     return 0; 
} 

有了提升,你可以用

#include <boost/lambda/lambda.hpp> 

... 

    using boost::lambda::_1; 
    std::vector<int>::iterator new_end = std::remove_if(x.begin(), x.end(), _1 > 2); 
+1

+1。我只是用'std :: copy(x.begin(),x.end(),std :: ostream_iterator(std :: cout,「」));來替換輸出行以隱藏循環。 ..但這只是一個品味:) – 2010-06-29 08:59:48

5

的C++ 0x(使用lambda表達式):

container.erase(std::remove_if(container.begin(), container.end(), 
           [](int v) { return v > 2; }), 
       container.end()); 

的原因eraseremove_if組合是STL算法適用於迭代器,而不是容器。他們重新定位容器的內容,但他們不會修改容器本身。

C++ 03:

container.erase(std::remove_if(container.begin(), container.end(), 
           std::bind2nd(std::greater<int>(), 2)), 
       container.end()); 

這似乎有點簡單,但它也不太靈活,因爲只有已經定義了這麼多的謂詞。對於更復雜的操作,您必須編寫自己的謂詞函子。

+0

愛0x lambdas – DanDan 2010-06-29 09:20:04

+0

我可以做MS視覺工作室? – 2010-06-29 09:27:35

+1

@Hellfrost:如果你使用VS2010,你可以。 – 2010-06-29 09:34:27

1

通過的方式,升壓::範圍v.1.46.0(2011年發佈)中有你想要什麼 - 在remove_erase_if算法

#include <boost/range/algorithm_ext/erase.hpp 

std::vector<int> vec = {1, 6, 2, 7}; 
boost::range::remove_erase_if(vec, [](int val){return val > 5;}); 

簡短易懂。