2013-07-05 129 views
6

我有一個std::map,我想從第二項開始迭代。爲什麼我不能做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>)':無法從'int'推導'std :: _ St​​ring_iterator < _Mystr>'的模板參數

任何人都可以解釋這裏發生了什麼?

+1

有史以來最奇怪的錯誤信息? – curiousguy

回答

11

std::map<T>::iterator是迭代器級的雙向迭代器。那些只有++--運營商。 +N[]僅適用於隨機訪問迭代器(可在例如std::vector<T>中找到)。

這背後的原因是,增加N隨機訪問迭代器是恆定的時間(例如添加N*sizeof(T)T*),而做同樣的事情了雙向迭代會要求申請++N倍。

你可以儘管做些什麼(如果你有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迭代器是雙向的,因此它們只提供++和 - 運算符,但不提供operator+,即使它是+1。
如果您確實需要模擬operator +,則可以使用std::advance,但這會導致爲迭代器調用的增量序列。

+1

爲什麼選擇抱怨字符串? – doctorlove

+0

這很有幫助,謝謝,雖然像@doctorlove,但我仍然不明白編譯器錯誤。我想知道其他編譯器的報告。 –

+0

@doctorlove那麼最好問問msvc編譯器開發人員。 gcc給出了所有可能的扣除。 http://ideone.com/UUz5Xr – alexrider

相關問題