2013-02-26 57 views
0

基本上我有幾種情況,我使用boost::filter_iterator來過濾某些條件的迭代器。有一種情況,我想同時過濾兩種情況,並且我們已經有一些預先存在的代碼,但是我想知道是否有一種慣用的方法可以通過增強或標準庫來實現:任何使用boost MPL或類似的迭代器過濾器的方法

/*! TODO: Surely there should be something in std/boost to achieve this??? */ 
    /*! Filter for things that satisfy F1 and F2 */ 
    template < 
     typename F1, 
     typename F2, 
     typename ArgT 
    > 
    struct filter_and 
    { 
     F1 f1; 
     F2 f2; 

     filter_and(F1 _f1, F2 _f2): f1(_f1), f2(_f2) 
     {} 

     inline bool operator() (ArgT const& arg) const 
     { 
      return f1(arg) && f2(arg); 
     } 
    }; 

如果解決方案需要C++ 11,只要最新的MSVC可以處理它就應該沒問題。

+2

爲什麼不把兩個迭代器疊加在一起? – ipc 2013-02-26 20:17:18

+0

@ipc,我其實並沒有想到這樣做,也許這是一個不錯的選擇。 – shuttle87 2013-02-26 20:43:42

回答

1

試試這個:make_filter_iterator(it, [=](value_type const& v) { return f1(v) && f2(v); });

對於一些發燒友...

bool and_in_order() { return true; } 
template<typename F0, typename Funcs...> 
bool and_in_order(F0&& f0, Funcs&&... funcs) { 
    return f0() && and_in_order(funcs...); 
} 

template<typename... Funcs> 
struct and_unary_functors { 
    std::tuple<Funcs...> funcs; 
    template<typename Arg, typename seq=typename make_seq<sizeof...(Funcs)>::type> 
    bool operator()(Arg&& arg) const; 

    template<typename Arg, int...s> 
    bool operator()<Arg, seq<s...>>(Arg&& arg) const { 
    return and_in_order([&](){ return get<s>(funcs)(arg); }...); 
    } 
}; 

template<typename... Funcs> 
and_unary_functors<Funcs> make_and_unary(Funcs const&... funcs) { 
    return {std::make_tuple(funcs...)}; 
}; 

auto filter_it = make_filter_iterator(base_iterator, make_and_unary(f1, f2, f3, f4)); 

或一些愚蠢這樣。