Boost C++ 库

……是世界上最受推崇、设计最精湛的 C++ 库项目之一。 Herb SutterAndrei Alexandrescu, C++ Coding Standards

计数迭代器 - Boost C++ 函数库

计数迭代器

作者 David Abrahams, Jeremy Siek, Thomas Witt
联系方式 dave@boost-consulting.com, jsiek@osl.iu.edu, witt@ive.uni-hannover.de
组织 Boost Consulting, Indiana University Open Systems Lab, University of Hanover Institute for Transport Railway Operation and Construction
日期 2006-09-11
版权 Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003.
摘要

您将如何使用来将数字零到一百填入一个 vector 中?std::copy()内置整数类型中唯一缺失的迭代器操作是operator*()返回整数当前值的操作。计数迭代器适配器为它包装的任何类型添加了这一关键功能。计数迭代器适配器不仅可以与整数类型一起使用,还可以与任何可增量类型一起使用。

counting_iterator通过添加一个operator*来适配一个对象,该对象返回对象的当前值。所有其他迭代器操作都转发给被适配的对象。

counting_iterator概要

template <
    class Incrementable
  , class CategoryOrTraversal = use_default
  , class Difference = use_default
>
class counting_iterator
{
public:
    typedef Incrementable value_type;
    typedef const Incrementable& reference;
    typedef const Incrementable* pointer;
    typedef /* see below */ difference_type;
    typedef /* see below */ iterator_category;

    counting_iterator();
    counting_iterator(counting_iterator const& rhs);
    explicit counting_iterator(Incrementable x);
    Incrementable const& base() const;
    reference operator*() const;
    counting_iterator& operator++();
    counting_iterator& operator--();
private:
    Incrementable m_inc; // exposition
};

如果差值参数是use_defaultdifference_type是一个未指定的带符号整型类型。否则difference_type差值.

iterator_category是根据以下算法确定的

if (CategoryOrTraversal is not use_default)
    return CategoryOrTraversal
else if (numeric_limits<Incrementable>::is_specialized)
    return iterator-category(
        random_access_traversal_tag, Incrementable, const Incrementable&)
else
    return iterator-category(
         iterator_traversal<Incrementable>::type,
         Incrementable, const Incrementable&)
[注意:鼓励实现者提供
operator-difference_type的实现,并在std::numeric_limits<Incrementable>::is_specialized为 true 的情况下避免溢出。]

counting_iteratorrequirements

Incrementable参数应该是 Copy Constructible 和 Assignable 的。

如果iterator_category可转换为forward_iterator_tagforward_traversal_tag,则以下语句必须是 well-formed 的

Incrementable i, j;
++i;         // pre-increment
i == j;      // operator equal

如果iterator_category可转换为bidirectional_iterator_tagbidirectional_traversal_tag,则以下表达式必须也是 well-formed 的

--i

如果iterator_category可转换为random_access_iterator_tagrandom_access_traversal_tag,则以下语句必须也是有效的

counting_iterator::difference_type n;
i += n;
n = i - j;
i < j;

counting_iterator模型

的特化counting_iterator模型 Readable Lvalue Iterator。此外,它们还模型与其iterator_category可转换的迭代器标签相对应的概念。另外,如果CategoryOrTraversal不是use_defaultcounting_iterator模型与迭代器标签相对应的概念CategoryOrTraversal。否则,如果numeric_limits<Incrementable>::is_specialized,那么counting_iterator模型 Random Access Traversal Iterator。否则,counting_iterator模型与Incrementable.

counting_iterator<X,C1,D1>counting_iterator<Y,C2,D2>当且仅当XY.

counting_iterator操作

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

counting_iterator();

要求Incrementable是 Default Constructible 的。
效果默认构造成员m_inc.

counting_iterator(counting_iterator const& rhs);

效果构造成员m_inctemplate< class PtrSequence > void transfer( iterator before, typename PtrSequence::iterator object, PtrSequence& from );rhs.m_inc.

explicit counting_iterator(Incrementable x);

效果构造成员m_inctemplate< class PtrSequence > void transfer( iterator before, typename PtrSequence::iterator object, PtrSequence& from );x.

reference operator*() const;

返回m_inc

counting_iterator& operator++();

效果++m_inc
返回*this

counting_iterator& operator--();

效果--m_inc
返回*this

Incrementable const& base() const;

返回m_inc
template <class Incrementable>
counting_iterator<Incrementable> make_counting_iterator(Incrementable x);
返回的一个实例counting_iterator<Incrementable>带有当前由...构造x.

示例

此示例使用来填充一个包含数字的数组和一个包含指向第一个数组的指针的第二个数组。counting_iterator两者都要完成。最后indirect_iterator用于通过第二个数组的间接访问打印出第一个数组中的数字。

int N = 7;
std::vector<int> numbers;
typedef std::vector<int>::iterator n_iter;
std::copy(boost::counting_iterator<int>(0),
         boost::counting_iterator<int>(N),
         std::back_inserter(numbers));

std::vector<std::vector<int>::iterator> pointers;
std::copy(boost::make_counting_iterator(numbers.begin()),
          boost::make_counting_iterator(numbers.end()),
          std::back_inserter(pointers));

std::cout << "indirectly printing out the numbers from 0 to "
          << N << std::endl;
std::copy(boost::make_indirect_iterator(pointers.begin()),
          boost::make_indirect_iterator(pointers.end()),
          std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;

找到。输出是

indirectly printing out the numbers from 0 to 7
0 1 2 3 4 5 6

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