http://www.cplusplus.com/reference/std/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
(これらのtypedefを持つ)から継承することができます。名前空間の変更を避け、読みやすくするために、2番目のオプションを好みます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
std::random_access_iterator_tag
std::next
std::prev
std::advance
std::distance
std::begin
std::end
コンテナにはおそらく、も含まれている必要があります。これは、から暗黙的に構築可能であり、ユーザーがデータを変更できないことを除いてconst_iterator
、と同様の定数データへの(おそらく可変の)イテレータです。内部ポインタが非定数データへのポインタであるのが一般的であり、コードの重複を最小限に抑えるためにから継承しています。iterator
iterator
iterator
const_iterator
独自のSTLコンテナーの作成に関する私の投稿には、より完全なコンテナー/イテレーターのプロトタイプがあります。