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"也要好好理解