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.
摘要 反向迭代器适配器以相反的方向遍历适配的迭代器范围。

reverse_iterator概要

template <class Iterator>
class reverse_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;

  reverse_iterator() {}
  explicit reverse_iterator(Iterator x) ;

  template<class OtherIterator>
  reverse_iterator(
      reverse_iterator<OtherIterator> const& r
    , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
  );
  Iterator const& base() const;
  reference operator*() const;
  reverse_iterator& operator++();
  reverse_iterator& operator--();
private:
  Iterator m_iterator; // exposition
};

如果Iterator模拟随机访问遍历迭代器和可读左值迭代器,然后iterator_category可转换为random_access_iterator_tag。否则,如果Iterator模拟双向遍历迭代器和可读左值迭代器,则iterator_category可转换为bidirectional_iterator_tag。否则,iterator_category可转换为input_iterator_tag.

reverse_iteratorrequirements

Iterator必须是双向遍历迭代器的模型。类型iterator_traits<Iterator>::reference必须是*i,其中i是一个对象,类型为Iterator.

reverse_iterator模型

一个特化reverse_iterator模拟与其Iterator参数相同的迭代器遍历和迭代器访问概念。此外,它可能模拟下表中指定的旧迭代器概念

如果I模型 reverse_iterator<I>模型
可读左值迭代器(Readable Lvalue Iterator)、双向遍历迭代器(Bidirectional Traversal Iterator) 双向迭代器(Bidirectional Iterator)
可写左值迭代器(Writable Lvalue Iterator)、双向遍历迭代器(Bidirectional Traversal Iterator) 可变双向迭代器(Mutable Bidirectional Iterator)
可读左值迭代器(Readable Lvalue Iterator)、随机访问遍历迭代器(Random Access Traversal Iterator) 随机访问迭代器
可写左值迭代器(Writable Lvalue Iterator)、随机访问遍历迭代器(Random Access Traversal Iterator) 可变随机访问迭代器(Mutable Random Access Iterator)

reverse_iterator<X>reverse_iterator<Y>当且仅当XY.

reverse_iterator操作

除了参数所模拟的概念所要求的操作之外,reverse_iterator, reverse_iterator还提供了以下操作。

reverse_iterator();

要求Iterator必须是默认可构造的。
效果构造一个实例reverse_iterator带有m_iterator默认构造。

explicit reverse_iterator(Iterator x);

效果构造一个实例reverse_iterator带有m_iterator从...复制构造x.
template<class OtherIterator>
reverse_iterator(
    reverse_iterator<OtherIterator> const& r
  , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
);
要求OtherIterator隐式转换为Iterator.
效果构造实例reverse_iteratorm_iterator子对象由...构造y.base().

Iterator const& base() const;

返回m_iterator

reference operator*() const;

效果
Iterator tmp = m_iterator;
return *--tmp;

reverse_iterator& operator++();

效果--m_iterator
返回*this

reverse_iterator& operator--();

效果++m_iterator
返回*this
template <class BidirectionalIterator>
reverse_iterator<BidirectionalIterator>n
make_reverse_iterator(BidirectionalIterator x);
返回的一个实例reverse_iterator<BidirectionalIterator>使用一个当前由...构造x.

示例

以下示例使用反向迭代器按相反顺序打印字符数组reverse_iterator.

char letters_[] = "hello world!";
const int N = sizeof(letters_)/sizeof(char) - 1;
typedef char* base_iterator;
base_iterator letters(letters_);
std::cout << "original sequence of letters:\t\t\t" << letters_ << std::endl;

boost::reverse_iterator<base_iterator>
  reverse_letters_first(letters + N),
  reverse_letters_last(letters);

std::cout << "sequence in reverse order:\t\t\t";
std::copy(reverse_letters_first, reverse_letters_last,
          std::ostream_iterator<char>(std::cout));
std::cout << std::endl;

std::cout << "sequence in double-reversed (normal) order:\t";
std::copy(boost::make_reverse_iterator(reverse_letters_last),
          boost::make_reverse_iterator(reverse_letters_first),
          std::ostream_iterator<char>(std::cout));
std::cout << std::endl;

找到。输出是

original sequence of letters:                   hello world!
sequence in reverse order:                      !dlrow olleh
sequence in double-reversed (normal) order:     hello world!

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