2009-03-22 13 views
162

私はstlベクトルの要素にindex []でアクセスするコードを書いていましたが、今はベクトルの塊だけをコピーする必要があります。それはvector.insert(pos, first, last)のように私が望む機能です...私はintとして最初と最後を除いている。これらの値にイテレータを使うことができますか?C++ STL Vectors:インデックスからイテレータを取得しますか?

+1

も参照してください:http://stackoverflow.com/q/2152986/365102 –

答えて

234

はこれを試してみてください:

vector<Type>::iterator nth = v.begin() + index; 
+4

一般的に、あなたはよりもSTLのイテレータと同じ算術演算を使用することができますポインタ。これらは、STLアルゴリズムを使用するときに交換可能に設計されています。 –

+14

@VincentRobert:他の方法で。ポインタは、最も強力なカテゴリであるSTLランダムイテレータの有効な実装です。しかし、前方イテレータなどの他の強力でないカテゴリは、同じ算術をサポートしていません。 – MSalters

+0

私はこの答えに5セントを追加し、 'std :: next(v.begin()、index)'を推奨しません。 – stryku

75

ベクトル

のための素晴らしいと高速@dirkgently (v.begin() + index)で述べた方法ではなくstd::advance(v.begin(), index)最も一般的な方法とランダムアクセスイテレータのためには、あまりにも、一定の時間を動作します。

EDIT使用量の
違い:

std::vector<>::iterator it = (v.begin() + index); 

または

std::vector<>::iterator it = v.begin(); 
std::advance(it, index); 

@litbノートの後に追加

+0

std :: advanceではなく、最初の引数として非constイテレータが必要ですか?これに応じて – goldPseudo

+0

- http://www.sgi.com/tech/stl/advance.html - いいえ。 – bayda

+0

std :: advanceをconstとnon-constイテレータで使用することができます – bayda

-3

Actutally std :: vectorは、必要なときにCタブとして使用するためのものです。 (C++のベクトルの実装のために、私の知る限りでは、標準的な要求 - replacement for array in Wikipedia)例えば このfolowingを行うことは完全に合法である私に従っ:もちろん

int main() 
{ 

void foo(const char *); 

sdt::vector<char> vec; 
vec.push_back('h'); 
vec.push_back('e'); 
vec.push_back('l'); 
vec.push_back('l'); 
vec.push_back('o'); 
vec.push_back('/0'); 

foo(&vec[0]); 
} 

、どちらかのfooはアドレスをコピーしてはなりませんパラメータとして渡され、どこかに格納されます。また、vec内の新しい項目を決して押したり、容量を変更することを要求したりしないようにプログラムで確保する必要があります。またはリスクのセグメンテーションフォールト...

は、したがって、あなたのexempleで、それは

vector.insert(pos, &vec[first_index], &vec[last_index]); 
+0

私は、なぜ彼らがポインタであればイテレータに抽象化することを決めたのだろうかと疑問に思います...彼らは本質的にこれらの機能を隠しています。 – mpen

+0

コンプライアンスのために?コード内の他の種類のコンテナのベクターインスタンスも簡単に削除できます。 –

+4

&vec [i]はvector <> :: iteratorと必ずしも互換性のないポインタを生成します。 vec.begin()+私はまだあなたのライブラリがそれを定義するイテレータであれば何でもできるという利点があります。たとえば、デバッグモードでのチェックイテレータを含みます。したがって、ポインタ(I/Oなど)を必要としない場合は、常にイテレータを使用する必要があります。 – sellibitze

7

につながるか、あなたはまたstd::advance

vector<int>::iterator i = L.begin(); 
advance(i, 2); 
33

を使用することができます。 auto it = std::next(v.begin(), index);

アップデート:C++ 11X対応のコンパイラが必要

+2

これはC++ 11の方法であることに注意してください! std :: nextはstd :: advanceと同じです。これらの関数を用いて算術演算を使うのではなく、スワッピングコンテナの型をもっと簡単にすることができます。また、std :: beginやstd :: endと同様に、C配列のafaikで動作します。 – Zoomulator

+2

std :: advanceは、戻り値ではなく出力として参照を使用するので、馬鹿によって設計されていることにも注意してください。 –

+1

for(auto it = begin(c); it!= end(c); advance(it、n)){...} – Zoomulator

関連する問題