https://cplusplus.com/reference/iterator/ https://cplusplus.com/reference/iterator/有一个方便的图表,详细介绍了 C++11 标准第 24.2.2 节的规范。基本上,迭代器具有描述有效操作的标签,并且标签具有层次结构。下面纯粹是象征性的,这些类实际上并不存在。
iterator {
iterator(const iterator&);
~iterator();
iterator& operator=(const iterator&);
iterator& operator++(); //prefix increment
reference operator*() const;
friend void swap(iterator& lhs, iterator& rhs); //C++11 I think
};
input_iterator : public virtual iterator {
iterator operator++(int); //postfix increment
value_type operator*() const;
pointer operator->() const;
friend bool operator==(const iterator&, const iterator&);
friend bool operator!=(const iterator&, const iterator&);
};
//once an input iterator has been dereferenced, it is
//undefined to dereference one before that.
output_iterator : public virtual iterator {
reference operator*() const;
iterator operator++(int); //postfix increment
};
//dereferences may only be on the left side of an assignment
//once an output iterator has been dereferenced, it is
//undefined to dereference one before that.
forward_iterator : input_iterator, output_iterator {
forward_iterator();
};
//multiple passes allowed
bidirectional_iterator : forward_iterator {
iterator& operator--(); //prefix decrement
iterator operator--(int); //postfix decrement
};
random_access_iterator : bidirectional_iterator {
friend bool operator<(const iterator&, const iterator&);
friend bool operator>(const iterator&, const iterator&);
friend bool operator<=(const iterator&, const iterator&);
friend bool operator>=(const iterator&, const iterator&);
iterator& operator+=(size_type);
friend iterator operator+(const iterator&, size_type);
friend iterator operator+(size_type, const iterator&);
iterator& operator-=(size_type);
friend iterator operator-(const iterator&, size_type);
friend difference_type operator-(iterator, iterator);
reference operator[](size_type) const;
};
contiguous_iterator : random_access_iterator { //C++17
}; //elements are stored contiguously in memory.
你可以专攻std::iterator_traits<youriterator>
,或者将相同的 typedef 放入迭代器本身,或者继承自std::iterator
(有这些类型定义)。我更喜欢第二种选择,以避免改变std
命名空间,并且为了可读性,但大多数人继承自std::iterator
.
struct std::iterator_traits<youriterator> {
typedef ???? difference_type; //almost always ptrdiff_t
typedef ???? value_type; //almost always T
typedef ???? reference; //almost always T& or const T&
typedef ???? pointer; //almost always T* or const T*
typedef ???? iterator_category; //usually std::forward_iterator_tag or similar
};
请注意 iterator_category 应该是以下之一std::input_iterator_tag
, std::output_iterator_tag
, std::forward_iterator_tag
, std::bidirectional_iterator_tag
, or std::random_access_iterator_tag
,取决于您的迭代器满足哪些要求。根据您的迭代器,您可以选择专门化std::next
, std::prev
, std::advance
, and std::distance
也是如此,但这很少需要。在极其罕见您可能希望专门研究的案例std::begin
and std::end
.
你的容器可能还应该有一个const_iterator
,这是一个(可能可变的)常量数据迭代器,类似于您的iterator
除非它应该可以从 a 隐式构造iterator
并且用户应该无法修改数据。其内部指针通常是指向非常量数据的指针,并且具有iterator
继承自const_iterator
从而尽量减少代码重复。
我的帖子在编写您自己的 STL 容器 https://stackoverflow.com/questions/7758580/writing-your-own-stl-container/7759622#7759622有更完整的容器/迭代器原型。