boost使用不同的谓词过滤迭代器

时间:2012-02-24 12:06:08

标签: c++ templates boost iterator polymorphism

我正在尝试实现一个返回boost :: filter_iterator对的方法(begin,end)。

我希望这个方法可以在过滤方面进行自定义,但是我不知道如何对它进行排序,因为当我输入过滤器迭代器范围时我必须对我想要使用的谓词进行硬编码而我无法选择它取决于方法在输入中接收的参数。

我想有这样的事情:

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);

谓词“基类”是基于枚举的实现的可能解决方案吗?

提前多多感谢! 贾科莫

1 个答案:

答案 0 :(得分: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,由于lambdas,创建谓词的行为变得更加容易。