咱們已經知道可使用下標運算符來訪問string
對象的字符或vector
對象的元素,還有另外一種更通用的機制也能夠實現一樣的目的,這就是迭代器(iterator)
。算法
標準庫容器均可以使用迭代器,可是隻有少數幾種才同時支持下標運算符。指針
相似於指針類型,迭代器
也提供了對對象
的間接訪問。就迭代器而言,其對象是容器中的元素或者string對象中的字符。使用迭代器能夠訪問某一個元素,迭代器也能從一個元素移動到另一個元素。迭代器和指針同樣,有無效和有效的區別。code
有效的迭代器指向元素或者尾元素的下一個位置,其餘狀況都屬於無效的迭代器。對象
可以使用迭代器的變量類型擁有返回迭代器的方法。get
begin()
方法負責返回指向第一個元素
的迭代器
end()
方法負責返回指向容器尾元素的下一個位置
的迭代器string
// b表示v的第一個元素,e表示v尾元素的下一個位置 auto b = v.begin(), e = v.end(); // b和e的類型相同
特殊狀況下:it
若是容器爲空,則
begin
和end
返回的是同一個迭代器。table
運算符 | 含義 |
---|---|
*iter | 返回迭代器iter所指元素的引用 |
iter->mem | 解引用iter並獲取該元素的名爲mem的成員,等價於*(iter).mem |
++iter | 令iter指向容器中的下一個元素 |
--iter | 令iter指向元素中的上一個元素 |
iter1 == iter2 | 判斷兩個迭代器是否相等 |
這使得迭代器就想下標同樣的好用,好比:class
string s("come thing"); if (s.begin() != s.end()) { auto it = s.begin(); *it = toupper(*it); }
就想不知道string
和vector
的site_type
成員究竟是什麼類型同樣,通常來講咱們也不知道迭代器的精確類型。而實際上,那些擁有迭代器的標準庫類型都會使用iterator
和const_iterator
來表示迭代器的類型:容器
vector<int>::iterator it; // it能表明vector<int>的元素 string::iterator it2; // it2能表明string對象中的元素 vector<int>::const_iterator it3; // it3只能表明讀元素,不能表明寫元素 string::const_iterator it4; // it4只能讀字符,不能寫字符,即改變字符的值
const_iterator
和常量指針差很少,能讀取但不能修改他所指元素的值。
若是vector對象或string對象是一個常量,只能使用
const_iterator
解引用能夠得到迭代器所指的對象,若是該對象的類型剛好是個類,就有可能進一步訪問他的成員。例如:
vector<string> strs = {"string", "", "tingyugetc"}; for (auto it = strs.begin(); it != strs.end() ; ++it) { if (it->empty()) { cout << "now is in empty string" << endl; } }
上述的代碼中使用了箭頭運算符
, 箭頭運算符將解引用和成員訪問兩個操做結合在一塊兒,他的做用和(*it).empty()
相同。
(*it).empty()
的圓括號必不可少,其含義是先執行括號內的解引用,接着解引用的結果在執行點運算符。若是不加括號,那麼點運算符將由it執行,而不是it解引用的結果。
某些對vector對象的操做會使迭代器失效.
謹記,但凡使用了迭代器的循環體,都不要想迭代器所屬的容器添加元素
迭代器的遞增運算令迭代器每次移動一個元素,全部的標準庫都有支持遞增運算符的迭代器。相似的,也能用==
和!=
對任意標準庫類型的兩個有效迭代器進行比較。
一樣的,能夠令迭代器和一個整數值相加或相減,其返回值是向前或向後移動了若干個位置的迭代器,執行這樣的操做時,結果迭代器要麼指向原vector對象內的一個元素要麼指向尾元素的下一個位置。
好比,能夠這樣:
// 計算獲得最接近vi中間元素的一個迭代器 auto mid = vi.begin() + vi.size() / 2;
使用迭代器運算的一個經典算法是二分搜索。
auto beg = text.begin(), end = text.end(); auto mid = beg + (end - beg) / 2; while (mid != end && *mid != found) { if (found < *mid) { end = mid; } else { beg = mid + 1; } mid = beg + (end - beg) / 2; }