2017-09-11 6 views
7

I understand (at least I think I do)このポインタは、ランダムなSTLイテレータとして使用できます。ポインタによるSTLベクタ消去

ポインタをイテレータにキャストしない限り、次のコードがコンパイルされないのはなぜですか?

vector<int> v{1, 2, 3}; 
v.erase(&v[0]); 
+12

なぜ要素へのポインタがイテレータ( 'std :: vector :: iterator')と同じであると思いますか? – NathanOliver

+1

どのようなエラーが表示されますか? –

+6

イテレータはポインタを使用して実装できますが、ポインタは自動的にイテレータではありません。 –

答えて

12

あなたはstd::sortstd::find、またはstd::copyようアルゴリズムへのポインタを渡すことができます。これらは、適切なイテレータとして機能するものに対して構成可能なテンプレートです。

これは、異なるイテレータが必ず相互に変換するという意味ではありません。

std::vector<int>コンテナのメソッドeraseは、イテレータと同じベクターの要素に対してのみ機能します。これはポインタとして実装されてもよい指摘し、それは通常はありませんが、ここに述べた理由のためにしたように: C++ std::vector<>::iterator is not a pointer, why?

std::findを考えてみましょう。ここで

template< class InputIt, class T > 
InputIt find(InputIt first, InputIt last, const T& value); 

InputItテンプレートパラメータです。テンプレートstd::findは、input iteratorの要件を満たし、operator*がタイプTと比較できるものを返すイテレータタイプで動作します。ポインタはここでうまくいきます。 Fire Lancerがコメントで正しく指摘したように、firstlastInputItである必要があります。

std::vector::eraseにこれを比較します

iterator erase(const_iterator pos); 

これはstd::vectorクラスの型定義の一つである、const_iteratorをとります。これはイテレータの特定のタイプであり、テンプレートパラメータではありません。

+1

これらのアルゴリズムへのポインタの**ペア**をうまく通過させることは事実上ランダムアクセスイテレータタイプです。しかし、ポインタがベクター内にあっても、ポインタとベクトル反復子をそれらの "ペア"として渡すことはできません。 –

1

vector.erase(...)の定義は

iterator erase(const_iterator pos);

const iterator自体のクラスです。 したがって、このクラスへのプレーン・ポインタの変換があった場合は、これを実行できます。しかし、私はそれがあるとは思わない。

しかし、イテレータが期待される場所で使用する方法と、アルゴリズムで使用する方法があります。

iteratorが必要な場合は、イテレータのみを使用できます。

アルゴリズムでは、iteratorは期待されません。 iteratorConceptが満たされているオブジェクト(通常はbeginendが必要なイテレータ/ポインタを返します)。

+0

アルゴリズムは、 "開始/終了...のオブジェクト"ではなく、イテレータを期待しています。 – juanchopanza

+1

アルゴリズムはテンプレートを使用します。パラメータは '' iterator'''の具体的な型ではありません。関数に '' iterator'''の概念を満たすオブジェクトを渡すことができます。 –

+0

正確に私のポイント。修正をありがとう。 – juanchopanza

0

ポインタはイテレータですが、彼らは同じタイプとしてベクトルイテレータ(少なくとも、彼らがする必要はありません)ではありません。

このように、イテレータとポインタ演算を使用して、ポインタをベクトルの要素に変換することができます。

std::vector<int> v{1, 2, 3}; 

int* p = &v[0]; // a pointer 

auto v_iter = v.begin() + std::distance(v.data(), p); // an equivalent vector::iterator 

v.erase(v_iter); 

std::vectorまたはstd::arrayのような連続した容器でのみ有効です。

関連する問題