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.
摘要

如何使用std::copy()将 0 到 100 的数字填入向量(vector)中?内置整数类型唯一缺失的迭代器操作是operator*(),它能返回整数的当前值。计数迭代器适配器(counting iterator adaptor)为它所包装的任何类型增添了这一关键功能。人们不仅可以将计数迭代器适配器用于整数类型,还可以将其用于任何可增量(incrementable)的类型。

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

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