web-dev-qa-db-ja.com

イテレータとポインタはどのように関連していますか?

イテレータを使用したコードは、ポインタを使用したコードによく似ています。イテレータは、あいまいなタイプ(std::vector<int>::iteratorなど)です。

イテレータとポインタがどのように相互に関連しているかはわかりません。イテレータは、隣接する要素に進むためのオーバーロードされた操作を持つポインタのラッパーですか、それとも他のものですか?

35
sharptooth

イテレータはポインタを一般化したものです。

イテレータ(バリアントによって異なります)は*および++を実装する必要があります

つまり、ポインタISイテレータです。ただし、必ずしもその逆ではありません。

複雑な構造(ツリー、グラフ...)を反復処理する場合、イテレータはポインタ以上のものであり、RAMの実際の場所への参照は行いません。

51

イテレータは特定の演算子をオーバーロードするオブジェクトなので、使用法はポインタのように見えます。これは、特定のイテレータカテゴリの機能の範囲内です。ランダムアクセスイテレータは完全にポインタのように見え、他のタイプのイテレータは一部の操作を提供しません(たとえば、双方向であるlist<X>::iteratorには、ランダムアクセスを必要とする他の多くの演算子の中で+=がありません)。

「あいまいな名前」に関しては、イテレーターに単純なポインターを使用することはまったく考えられないことではありません。

 template <class T>
 class MyContainer
 {
     ...
     typedef T* iterator;
 }

 MyContainer<int>::iterator it; //the type is really int*
9
UncleBens

概念的にはそうですが、ポインタである必要はありません。それらの内部と機能は、「ラップ」するデータ構造に依存します。

そのため、さまざまな イテレータの「クラス」 があります。例えば。単方向、双方向、ランダムアクセスなど.

いくつかは複数のクラスが可能です。

例えば。内部構造が赤黒ツリーまたはリンクリストの場合、イテレータは双方向である可能性がありますが、RandomAccessではありません。それらが(配列として実装された)ベクトルをラップする場合、RandomAccessとBidirectionalが得られます。

7
Alex Budovski

イテレーターは、イテレーターに必要なインターフェースを提供するタイプにすぎません。これらは、イテレーターのタイプによって異なり、C++標準(イテレーター要件)のセクション24.1で指定されています。

イテレータの実装方法は、イテレータの繰り返しに依存します。ベクトルの場合、イテレータは通常、配列への単一のポインタのラッパーです(リリースビルドではとにかく)、より複雑なコンテナの場合、実装はより複雑になります。オープンエンドの範囲の場合、要素の生成に使用されるアルゴリズムの状態が含まれます。

配列内の要素へのポインターはランダムアクセス反復子の要件を満たすため、ある程度互換性があることに注意してください。

4
JoeG