STL中的迭代器类似指针,但不仅仅是指针。迭代器和指针很像,功能很像指针,但是实际上,迭代器是通过重载一元的”*”和”->”来从容器中间接地返回一个值。将这些值存储在容器中并不是一个好主意,因为每当一个新值添加到容器中或者有一个值从容器中删除,这些值就会失效。在某种程度上,迭代器可以看作是句柄(handle)。通常情况下迭代器(iterator)的类型可以有所变化,这样容器也会有几种不同方式的转变: iterator——对于除了vector以外的其他任何容器,你可以通过这种迭代器在一次操作中在容器中朝向前的方向走一步。这意味着对于这种迭代器你只能使用“++”操作符。而不能使用“--”或“+=”操作符。而对于vector这一种容器,你可以使用“+=”、“—”、“++”、“-=”中的任何一种操作符和“<”、“<=”、“>”、“>=”、“==”、“!=”等比较运算符。 reverse_iterator ——如果你想用向后的方向而不是向前的方向的迭代器来遍历除vector之外的容器中的元素,你可以使用reverse_iterator 来反转遍历的方向,你还可以用rbegin()来代替begin(),用rend()代替end(),而此时的“++”操作符会朝向后的方向遍历。 const_iterator ——一个向前方向的迭代器,它返回一个常数值。你可以使用这种类型的迭代器来指向一个只读的值。 const_reverse_iterator ——一个朝反方向遍历的迭代器,它返回一个常数值。
混合迭代器函数
在涉及到容器和算法的操作中,还有两个迭代器函数非常有用:
· advance() 按指定的数目来增减迭代器。 template<class InIt, class Dist> void advance(InIt& it, Dist n); n为正时,递增第一个参数所传递的迭代器;n为负时,递减所传递的迭代器。
· distance() 返回到达一个迭代器所需(递增)操作的数目。 template<class Init, class Dist> Dist distance(InIt first, InIt last, Dist& n);
Distance is an overloaded name; there are actually two distance functions.
template <class InputIterator> inline iterator_traits<InputIterator>::difference_type distance(InputIterator first, InputIterator last);
template <class InputIterator, class Distance> void distance(InputIterator first, InputIterator last, Distance& n); 比较前后两个迭代器之间的数目。
例如:
list iList;
list::iterator p = find(iList.begin(), iList.end(), 2);
cout << "before: p == " << *p << endl;
advance(p, 2); // same as p = p + 2;
cout << "after : p == " << *p << endl;
int k = 0;
distance(p, iList.end(), k);
cout << "k == " << k << endl; // 返回两者之间的数目
advance()函数接受两个参数。第二个参数是向前推进的数目。对于前推迭代器,该值必须为正,而对于双向迭代器和随机访问迭代器,该值可以为负。
使用 distance()函数来返回到达另一个迭代器所需要的步骤。 注意 distance()函数是迭代的,也就是说,它递增第三个参数。因此,你必须初始化该参数。未初始化该参数几乎注定要失败。
distance () Sample Code:
// distance.cpp // compile with: /EHsc #pragma warning (disable:4786) #include <iostream> #include <vector> #include <iterator> #include <string> using namespace std; typedef vector<string > VTRLIST; int main() { VTRLIST Vector; VTRLIST::iterator iVector; VTRLIST::difference_type dTheDiff; Vector.push_back("A1"); Vector.push_back("B2"); Vector.push_back("C3"); Vector.push_back("D4"); Vector.push_back("E5"); Vector.push_back("F6"); Vector.push_back("G7"); // Print out the list iVector=Vector.begin(); cout << "The list is: "; for (int i = 0; i < 7 ; i++, iVector++) cout << *iVector << " "; // Initialize the iterator the first element" iVector=Vector.begin(); cout << "/n/nAdvance to the 3rd element." << endl; advance( iVector, 2); cout << "The element is " << *iVector << endl; dTheDiff = distance( Vector.begin(), iVector); cout << "The distance from the beginning is " << dTheDiff << endl; cout << "Calculate it in reverse order " << endl; dTheDiff = distance( iVector, Vector.begin()); cout << "The distance is " << dTheDiff << endl; cout << "/nUse distance() to count from the 3rd element to the end." << endl; dTheDiff = distance( iVector, Vector.end()); // Note that end() returns one past the end of the sequence cout << "The distance is " << dTheDiff << endl; cout <<"/nUse distance() to count the total length." << endl; dTheDiff = distance( Vector.begin(), Vector.end() ); cout << "The total distance is " << dTheDiff << endl; }
/* Output The list is: A1 B2 C3 D4 E5 F6 G7 Advance to the 3rd element. The element is C3 The distance from the beginning is 2 Calculate it in reverse order The distance is -2 Use distance() to count from the 3rd element to the end. The distance is 5 Use distance() to count the total length. The total distance is 7 */
advance() Sample Code:
// Advance.cpp // compile with: /EHsc #pragma warning (disable:4786) #include <iostream> #include <string> #include <list> using namespace std ; typedef list<string> STRLIST; int main() { STRLIST List; STRLIST::iterator iList; STRLIST::difference_type dTheDiff; List.push_back("A1"); List.push_back("B2"); List.push_back("C3"); List.push_back("D4"); List.push_back("E5"); List.push_back("F6"); List.push_back("G7"); // Print out the list iList=List.begin(); cout << "The list is: "; for (int i = 0; i < 7 ; i++, iList++) cout << *iList << " "; // Initialize to the first element" iList=List.begin(); cout << "/n/nAdvance to the 3rd element." << endl; advance(iList,2); cout << "The element is " << *iList << endl; }/* Output The list is: A1 B2 C3 D4 E5 F6 G7 Advance to the 3rd element. The element is C3 */
当然advance() 和distance() 还可以用来对const_iterator转换为iterator.
参考:《Effective STL 》条款27:用distance和advance把const_iterator转化成iterator
还有就是如果使用STL容器的反向迭代器时,"条款28:了解如何通过reverse_iterator的base得到iterator"也要好好理解