| 作者 | 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*来适配一个对象,该对象返回对象的当前值。所有其他迭代器操作都转发给被适配的对象。 |
|---|
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_default则difference_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&)
该Incrementable参数应该是 Copy Constructible 和 Assignable 的。
如果iterator_category可转换为forward_iterator_tag或forward_traversal_tag,则以下语句必须是 well-formed 的
Incrementable i, j; ++i; // pre-increment i == j; // operator equal
如果iterator_category可转换为bidirectional_iterator_tag或bidirectional_traversal_tag,则以下表达式必须也是 well-formed 的
--i
如果iterator_category可转换为random_access_iterator_tag或random_access_traversal_tag,则以下语句必须也是有效的
counting_iterator::difference_type n; i += n; n = i - j; i < j;
的特化counting_iterator模型 Readable Lvalue Iterator。此外,它们还模型与其iterator_category可转换的迭代器标签相对应的概念。另外,如果CategoryOrTraversal不是use_default则counting_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>当且仅当X与Y.
除了参数所模拟的概念所要求的操作之外,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
该示例的源代码可以在这里找到。