[解決済み】STLスタイルのイテレータを実装し、よくある落とし穴を回避する方法は?
質問
STLスタイルのランダムアクセス可能なイテレータを提供したいコレクションを作りました。イテレータの実装例を探していたのですが、見つかりませんでした。の const オーバーロードの必要性については知っています。
[]
と
*
演算子を使用することができます。イテレータが "STL-style"であるための要件と、(もしあれば)避けるべき他の落とし穴は何でしょうか?
追加の文脈 これはあるライブラリのためのもので、本当に必要でない限り、それへの依存性を導入したくありません。私は、同じコンパイラでC++03とC++11の間のバイナリ互換性を提供できるように、独自のコレクションを書いています(したがって、おそらく壊れるであろうSTLはありません)。
どのように解決するのですか?
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>
を継承するか、イテレータ自体に同じ型付けをするか、あるいは
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コンテナを自作する には、より完全なコンテナ/イテレータのプロトタイプがあります。
関連
-
[解決済み】ファイルから整数を読み込んで配列に格納する C++ 【クローズド
-
[解決済み】Visual Studioのデバッガーエラー。プログラムを開始できません 指定されたファイルが見つかりません
-
[解決済み】デバッグアサーションに失敗しました
-
[解決済み] 1ビットのセット、クリア、トグルはどのように行うのですか?
-
[解決済み] C++11では、標準化されたメモリモデルが導入されました。その意味するところは?そして、C++プログラミングにどのような影響を与えるのでしょうか?
-
[解決済み] IteratorをStreamに変換するには?
-
[解決済み] リファレンスとポインタの使い分け
-
[解決済み】イテレータ、イテラブル、イテレーションとは一体何ですか?
-
[解決済み】カスタムイテレータとconst_iteratorを正しく実装する方法は?
-
[解決済み】C++ STL Vectors: インデックスからイテレータを取得する?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] テスト
-
[解決済み】 != と =! の違いと例(C++の場合)
-
[解決済み】C++エラーです。"配列は中括弧で囲まれたイニシャライザーで初期化する必要がある"
-
[解決済み] error: 'if' の前に unqualified-id を期待した。
-
[解決済み】cc1plus:エラー:g++で認識されないコマンドラインオプション"-std=c++11"
-
[解決済み] 非静的データメンバの無効な使用
-
[解決済み] gdbを使用してもデバッグシンボルが見つからない
-
[解決済み] 配列のベクトルを扱う正しい方法
-
[解決済み】カスタムイテレータとconst_iteratorを正しく実装する方法は?
-
[解決済み] 独自のSTLコンテナを作成する