2010-05-13 72 views
9

我想爲STL list迭代器獲得較遠的下一個值,但它沒有實現operator+,vector雖然有。爲什麼以及如何獲得我想要的價值?爲什麼只有隨機訪問迭代器在C++中實現operator +?

我想我可以做到這一點,如果我打電話operator++幾次,但沒有那麼一點點髒?

我想要做的是以下幾點:

list<int> l; 
...omitted... 
list<int>::iterator itr = l.begin() + 3; // but, list iterator does not have 
             // operator+ 

什麼是我想要的最好的解決辦法?

+2

(幾乎)無關:您需要確保有可能達到此位置,否則您將調用未定義的行爲。雖然從'list :: begin()'很容易,但在更通用的情況下,知道(對於非RandomAccessIterator)與列表 :: end()相距的唯一方法是調用std ::距離...... O(N)。 – 2010-05-13 18:31:14

+0

這個主題有兩個很好的答案。 +1給社區! – 2010-05-13 18:46:32

回答

17

如果您無權訪問C++ 11,則還可以使用std::next(和prev)或Boost提供的等效項。

list<int>::iterator itr = std::next(l.begin(), 3); 

理由:std::advance是很難使用(它的工作原理是副作用,而不是返回一個副本)。

+2

很高興知道。我一直想知道爲什麼'std :: advance'是通過副作用而不是功能性的。 – 2010-05-13 18:32:48

+1

@RSam:我一直認爲這是因爲'std :: advance'是爲了模仿++ itr或operator + =,如果適當的話。迭代器算法通常用這些術語編寫,所以包裝它們是最有意義的。 – 2010-05-13 20:05:26

+0

如果你想要一個副本,你必須自己創建一個副本。這在C++中很常見。 – mschneider 2011-02-15 04:01:50

37

你想用std::advance

list<int>::iterator itr = l.begin(); 
std::advance(itr, 3); 

advance將使用operator+和完整在常數時間如果迭代器是隨機訪問,同時將循環在operator++和完整的線性時間,如果迭代器不是隨機訪問。  

原因是爲了讓您控制複雜性要求。如果你關心操作的複雜性,你可以使用operator+並且獲得恆定的時間,但是這隻能用隨機訪問迭代器進行編譯。如果你不關心你使用的複雜度std::advance,它將始終工作,但複雜度會根據迭代器而變化。

+3

+1簡單,清晰,徹底。 – wilhelmtell 2010-05-13 18:15:33

相關問題