2013-07-05 14 views
6

私はstd::mapを持っていますが、これは2番目のエントリから開始して繰り返します。なぜstd :: map.begin()+ 1を実行できないのですか?

私はこの問題を回避することができますが、なぜ「明白な」構文がコンパイルされないのか混乱しています。エラーメッセージは、ここで使用していないstd::stringを参照しているため役に立ちません。

ここにありますいくつかのコード

// suppose I have some map ... 
std::map<int, int> pSomeMap; 

// this is fine ... 
std::map<int, int>::const_iterator pIterOne = pSomeMap.begin(); 
++pIterOne; 

// this doesn't compile ... 
std::map<int, int>::const_iterator pIterTwo = pSomeMap.begin() + 1; 

VS2012与え、次のエラー上記の行に

エラーC2784:「STD :: _ St​​ring_iterator < _Mystr>のstd ::演算子+(_ String_iterator < _Mystr> :: difference_type、std :: _ St​​ring_iterator < _Mystr>) ':' std :: _ St​​ring_iterator < _Mystr> 'のテンプレート引数を' int 'から推測できません

ここで何が起こっているのか説明できる人はいますか?

+1

ほとんどの奇妙なエラーメッセージはこれまでありましたか? – curiousguy

答えて

11

std::map<T>::iteratorは、イテレータクラスのものです。双方向イテレータです。それらは++--の演算子しか持っていません。 +Nおよび[]は、ランダムアクセスイテレータ(例:std::vector<T>にあります)でのみ使用できます。

この背後にある理由は双方向イテレータのために同じことをやっては++N回を適用する必要になるのに対し、ランダムアクセスイテレータNを追加すると、一定の時間(例えばT*N*sizeof(T)を追加)であるということです。 (あなたがC++ 11を持っている場合)あなたがが何ができるか

は次のとおりです。すべてのイテレータ型のために正しいことをして

std::map<int, int>::const_iterator pIterTwo = std::next(pSomeMap.begin(),1); 

+2

それは優れています - 'std :: next'は私にとってもきれいに見えます。ありがとう+1。 –

+0

@RogerRowland 'std :: next'はC++ 11の追加です。しかし、C++ 11をお持ちでない場合は、 'std :: advance'を使って独自の' next'を実装するのは簡単です。あるいは、 'boost :: next'を使用してください。 – juanchopanza

+0

@juanchopanzaありがとう、私はVS2012を持っています。これはおそらくMSがC++ 11に近づく最も近いものです!コンパイルして正常に動作します。 –

6

std::mapイテレータは双方向であるため、++と - 演算子のみを提供しますが、+1であってもoperator+は提供しません。
実際にoperator +をシミュレートする必要がある場合はstd::advanceを使用できますが、イテレータに対して呼び出されるインクリメントのシーケンスになります。

+1

文字列について不平を言うのはなぜですか? – doctorlove

+0

これは参考になりました。ありがたいですが、@doctorloveのように、私はまだコンパイラエラーを理解していません。他のコンパイラが何を報告しているのだろうか。 –

+0

@doctorlove msvcコンパイラ開発者に尋ねる方がいいです。 gccはすべての可能な控除を行います。 http://ideone.com/UUz5Xr – alexrider

関連する問題