Boost C++ 库

……世界上最受推崇且设计最专业的 C++ 库项目之一。 Herb SutterAndrei Alexandrescu,《C++ 编码规范

过滤迭代器 - Boost C++ 函数库

过滤迭代器

作者 David Abrahams, Jeremy Siek, Thomas Witt
联系方式 dave@boost-consulting.com, jsiek@osl.iu.edu, witt@ive.uni-hannover.de
组织 Boost Consulting, 印第安纳大学 Open Systems Lab, 汉诺威大学 运输铁路运营与建设研究所
日期 2006-09-11
版权 Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003.
摘要 filter 迭代器适配器创建了一个迭代器范围的视图,其中某些范围内的元素将被跳过。一个谓词函数对象控制哪些元素被跳过。当谓词应用于一个元素时,如果它返回true则该元素被保留,如果它返回false那么元素就会被跳过。在跳过元素时,过滤适配器需要知道何时停止,以避免超出底层范围的末尾。因此,过滤迭代器是使用一对迭代器构造的,这对迭代器指示未过滤序列中要遍历的元素范围。

filter_iterator概要

template <class Predicate, class Iterator>
class filter_iterator
{
 public:
    typedef iterator_traits<Iterator>::value_type value_type;
    typedef iterator_traits<Iterator>::reference reference;
    typedef iterator_traits<Iterator>::pointer pointer;
    typedef iterator_traits<Iterator>::difference_type difference_type;
    typedef /* see below */ iterator_category;

    filter_iterator();
    filter_iterator(Predicate f, Iterator x, Iterator end = Iterator());
    filter_iterator(Iterator x, Iterator end = Iterator());
    template<class OtherIterator>
    filter_iterator(
        filter_iterator<Predicate, OtherIterator> const& t
        , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
        );
    Predicate predicate() const;
    Iterator end() const;
    Iterator const& base() const;
    reference operator*() const;
    filter_iterator& operator++();
private:
    Predicate m_pred; // exposition only
    Iterator m_iter;  // exposition only
    Iterator m_end;   // exposition only
};

如果Iterator模型 Readable Lvalue Iterator 和 Bidirectional Traversal Iterator,然后iterator_category可转换为std::bidirectional_iterator_tag。否则,如果Iterator模型 Readable Lvalue Iterator 和 Forward Traversal Iterator,然后iterator_category可转换为std::forward_iterator_tag否则iterator_category可转换为std::input_iterator_tag.

filter_iteratorrequirements

Iterator参数必须满足 Readable Iterator 和 Single Pass Iterator 的要求,或者满足 Input Iterator 的要求。

谓词参数必须是 Assignable、Copy Constructible,并且表达式p(x)必须是有效的,其中p是一个对象,类型为谓词, x是一个对象,类型为iterator_traits<Iterator>::value_type的 const 对象,其中p(x)必须可转换为bool.

filter_iterator模型

模型filter_iterator的模型取决于Iterator参数模型,具体如下表所示。

如果Iterator模型 filter_iterator模型
单次遍历迭代器 单次遍历迭代器
前向遍历迭代器 前向遍历迭代器
双向遍历迭代器 双向遍历迭代器
如果Iterator模型 filter_iterator模型
可读迭代器 可读迭代器
可写迭代器 可写迭代器
左值迭代器 左值迭代器
如果Iterator模型 filter_iterator模型
Readable Iterator, Single Pass Iterator 输入迭代器
Readable Lvalue Iterator, Forward Traversal Iterator 前向迭代器
Writable Lvalue Iterator, Forward Traversal Iterator Mutable Forward Iterator
Writable Lvalue Iterator, Bidirectional Iterator 可变双向迭代器(Mutable Bidirectional Iterator)

filter_iterator<P1, X>filter_iterator<P2, Y>当且仅当XY.

filter_iterator操作

除了概念所要求的那些操作外,filter_iterator满足,filter_iterator还提供了以下操作。

filter_iterator();

要求谓词andIterator必须是默认可构造的。
效果构造一个filter_iterator其``m_pred``、m_iterm_end成员是默认构造的。

filter_iterator(Predicate f, Iterator x, Iterator end = Iterator());

效果构造一个filter_iterator其中m_iter是在范围[x,end)使得f(*m_iter) == true或``m_iter == end`` 的第一个位置。成员m_pred是从fandm_endtemplate< class PtrSequence > void transfer( iterator before, typename PtrSequence::iterator object, PtrSequence& from );end.

filter_iterator(Iterator x, Iterator end = Iterator());

要求谓词必须是 Default Constructible 并且谓词是一个类类型(不是函数指针)。
效果构造一个filter_iterator其中m_iter是在范围[x,end)使得m_pred(*m_iter) == true或``m_iter == end`` 的第一个位置。成员m_pred是默认构造的。
template <class OtherIterator>
filter_iterator(
    filter_iterator<Predicate, OtherIterator> const& t
    , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
    );``
要求OtherIterator隐式转换为Iterator.
效果构造一个 filter 迭代器,其成员是从复制的t.

Predicate predicate() const;

返回m_pred

Iterator end() const;

返回m_end

Iterator const& base() const;

返回m_iterator

reference operator*() const;

返回*m_iter

filter_iterator& operator++();

效果增加m_iter然后继续增加m_iter直到m_iter == m_endm_pred(*m_iter) == true.
返回*this
template <class Predicate, class Iterator>
filter_iterator<Predicate,Iterator>
make_filter_iterator(Predicate f, Iterator x, Iterator end = Iterator());
返回filter_iterator<Predicate,Iterator>(f, x, end)
template <class Predicate, class Iterator>
filter_iterator<Predicate,Iterator>
make_filter_iterator(Iterator x, Iterator end = Iterator());
返回filter_iterator<Predicate,Iterator>(x, end)

示例

本示例使用了filter_iterator然后make_filter_iterator来仅输出整数数组中的正整数。然后make_filter_iterator它被用于输出大于-2.

struct is_positive_number {
  bool operator()(int x) { return 0 < x; }
};

int main()
{
  int numbers_[] = { 0, -1, 4, -3, 5, 8, -2 };
  const int N = sizeof(numbers_)/sizeof(int);

  typedef int* base_iterator;
  base_iterator numbers(numbers_);

  // Example using filter_iterator
  typedef boost::filter_iterator<is_positive_number, base_iterator>
    FilterIter;

  is_positive_number predicate;
  FilterIter filter_iter_first(predicate, numbers, numbers + N);
  FilterIter filter_iter_last(predicate, numbers + N, numbers + N);

  std::copy(filter_iter_first, filter_iter_last, std::ostream_iterator<int>(std::cout, " "));
  std::cout << std::endl;

  // Example using make_filter_iterator()
  std::copy(boost::make_filter_iterator<is_positive_number>(numbers, numbers + N),
            boost::make_filter_iterator<is_positive_number>(numbers + N, numbers + N),
            std::ostream_iterator<int>(std::cout, " "));
  std::cout << std::endl;

  // Another example using make_filter_iterator()
  std::copy(
      boost::make_filter_iterator(
          std::bind2nd(std::greater<int>(), -2)
        , numbers, numbers + N)

    , boost::make_filter_iterator(
          std::bind2nd(std::greater<int>(), -2)
        , numbers + N, numbers + N)

    , std::ostream_iterator<int>(std::cout, " ")
  );

  std::cout << std::endl;

  return boost::exit_success;
}

找到。输出是

4 5 8
4 5 8
0 -1 4 5 8

本示例的源代码可以在这里找到。