【问题标题】:boost Filter iterator with different predicates使用不同谓词提升过滤器迭代器
【发布时间】:2026-01-17 18:15:01
【问题描述】:

我正在尝试实现一个返回 boost::filter_iterator 对(开始,结束)的方法。

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

我想要这样的东西:

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

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

提前非常感谢! 贾科莫

【问题讨论】:

    标签: c++ templates boost iterator polymorphism


    【解决方案1】:

    为什么不简单地提供预定义的谓词而不是枚举值?

    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,创建谓词的操作变得更加容易。

    【讨论】: