2012-02-24 56 views
2

我想實現一個返回boost :: filter_iterator對(begin,end)的方法。boost使用不同謂詞的迭代器

我希望這種方法可以根據過濾進行定製,但是我不知道我是如何解決這個問題的,因爲當我typedef過濾器迭代器範圍時,我必須對我想使用的謂詞進行硬編碼,而且我不能根據方法在輸入中接收的參數選擇它。

我想有這樣的事情:

enum FilterType 
{ 
    FilterOnState = 0, 
    FilterOnValue, 
    FilterOnSize, 
    FilterOnWhatever... 
} 

typedef boost::filter_iterator<PredicateStruct, std::list<Object>::iterator> filter_iterator; 

std::pair<filter_iterator, filter_iterator> filterObjects(FilterType filterType); 

我想到了一個可能的模板解決方案爲好,但我需要的客戶端訪問謂詞執行和實例一相適應自己的需要調用之前過濾器,他幾乎可以自己完成所有工作:這就是爲什麼我最喜歡基於枚舉的解決方案。

template<typename P> 
std::pair<boost::filter_iterator<P, std::list<Object>::iterator>, 
      boost::filter_iterator<P, std::list<Object>::iterator>> filterObjects(P& predicate); 

謂詞「基類」是基於枚舉的實現的可能解決方案嗎?

非常感謝! Giacomo

回答

2

爲什麼不簡單地提供預定義的謂詞而不是枚舉值?

struct predef_predicate{ 
    predef_predicate(FilterType f) 
    : filt(f) {} 

    template<class T> 
    bool operator()(T const& v) const{ 
    // filter in whatever way... 
    } 

private: 
    FilterType filt; 
}; 

namespace { // guard against ODR violations 
predef_predicate const filter_state(FilterOnState); 
predef_predicate const filter_values(FilterOnValue); 
// ... 
} 

然後,而不是另起爐竈,只需使用Boost.Range's filtered adaptor

#include <vector> 
#include <iterator> 
#include <boost/range/adaptor/filtered.hpp> 
#include <boost/range/algorith/copy.hpp> 

int main(){ 
    std::vector<int> v; 
    // fill v 
    std::vector<int> filtered; 
    boost::copy(v | boost::adaptors::filtered(filter_values), 
     std::back_inserter(filtered)); 
} 

而在C++ 11中,由於lambda表達式,創建謂詞的行爲變得更加容易。