编写迭代器实际上是一项相当简单的任务,但它变得非常乏味。由于您的容器支持按整数索引,我假设它的迭代器将属于随机访问迭代器类别(如果它们存在)。这需要很多样板!
但是,为了支持基于范围的 for 循环,您只需要一个前向迭代器。我们将为实现前向迭代器要求的容器编写一个简单的包装器,然后编写两个函数Iterator begin(Container&)
,Iterator end(Container&)
使容器能够在基于范围的 for 循环中使用。
这Iterator
将包含对容器的引用、容器的大小以及该容器内的当前索引:
template<template<typename> class C, typename T>
class indexer : public std::iterator<std::forward_iterator, T>
{
public:
indexer(C<T>& c, std::size_t i, std::size_t end)
: c_(std::addressof(c)), i_(i), end_(end) {}
T& operator*() const {
return c_[i_];
}
indexer<C, T>& operator++() {
++i_;
return *this;
}
indexer<C, T> operator++(int) {
auto&& tmp = *this;
operator++();
return tmp;
}
bool operator==(indexer<C, T> const& other) const {
return i_ == other.i_;
}
bool operator!=(indexer<C, T> const& other) const {
return !(*this == other);
}
private:
C<T>* c_;
std::size_t i_, end_;
};
继承 fromstd::iterator
方便地声明适当的 typedef 以用于std::iterator_traits
.
然后,您将定义begin
和end
如下:
template<typename T>
indexer<Container, T> begin(Container<T>& c) {
return indexer<Container, T>(c, 0, c.size());
}
template<typename T>
indexer<Container, T> end(Container<T>& c) {
auto size = c.size();
return indexer<Container, T>(c, size, size);
}
切换到您示例Container
中的任何类型,container
这样,您想要的用法就可以了!
所有各种迭代器的要求和行为都可以在标准第 24.2.2 节的表格中找到,这些表格反映在cppreference.com 此处。
vector_view
可以在Coliru或ideone.com上找到上述的随机访问迭代器实现,以及一个简单类的使用演示。