C++标准模板库 迭代器 iterator 详解(一)

  1. #include <vector>  
  2. #include <iostream>  
  3. #include <list>  
  4. #include <algorithm>  
  5. #include <iterator> //copy  
  6. using namespace std;  
  7.   
  8. template <class T>  
  9. inline void print (const T& coll, const char* optcstr="")  
  10. {  
  11.     typename T::const_iterator pos;  
  12.   
  13.     std::cout << optcstr;  
  14.     for (pos=coll.begin(); pos!=coll.end(); ++pos)  
  15.     {  
  16.         std::cout << *pos << ' ';  
  17.     }  
  18.     std::cout << std::endl;  
  19. }  
  20.   
  21. void  test_random_access_iterator()  
  22. {  
  23.    vector<int> coll;  
  24.     // insert elements from 1991 to 2013  
  25.    for (int i=1991; i<=2013; ++i)  
  26.    {  
  27.        coll.push_back (i);  
  28.    }  
  29.   
  30.    /* print number of elements by processing the distance between beginning and end 
  31.     * - NOTE: uses operator - for iterators 
  32.     */  
  33.    cout << "number/distance: " << coll.end()-coll.begin() << endl;  
  34.   
  35.    /* print all elements 
  36.     * - NOTE: uses operator < instead of operator != 
  37.     */  
  38.    vector<int>::iterator pos;  
  39.    for (pos=coll.begin(); pos<coll.end(); ++pos)  
  40.    {  
  41.        cout << *pos << ' ';  
  42.    }  
  43.    cout << endl;  
  44.   
  45.    /* print all elements 
  46.     * - NOTE: uses operator [] instead of operator * 
  47.     */  
  48.    for (int i=0; i<coll.size(); ++i)  
  49.    {  
  50.        //cout << coll.begin()[i] << ' '; 和如下语句效果相同  
  51.        cout << coll[i] << ' ';  
  52.    }  
  53.    cout << endl;  
  54.   
  55.    /* print every second element 
  56.     * - NOTE: uses operator += 
  57.     */  
  58.    for (pos = coll.begin(); pos < coll.end()-1; pos += 2)  
  59.    {  
  60.        cout << *pos << ' ';  
  61.    }  
  62.    cout << endl;  
  63. }  
  64. /******************************************** 
  65. 运行结果: 
  66. number/distance: 23 
  67. 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 
  68. 2007 2008 2009 2010 2011 2012 2013 
  69. 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 
  70. 2007 2008 2009 2010 2011 2012 2013 
  71. 1991 1993 1995 1997 1999 2001 2003 2005 2007 2009 2011 
  72. *********************************************/  
  73. void test_advance()  
  74. {  
  75.     list<int> coll;  
  76.     // insert elements from 1 to 9  
  77.     for (int i=2007; i<=2014; ++i)  
  78.     {  
  79.         coll.push_back(i);  
  80.     }  
  81.     //打印整个链表  
  82.     print(coll,"print the list as follow:\n");  
  83.     list<int>::iterator pos = coll.begin();  
  84.     // print actual element  
  85.     cout<<endl;  
  86.     cout << *pos << endl;  
  87.     // step three elements forward  
  88.     cout<<endl<<"after advance (pos, 3)\n";  
  89.     advance (pos, 3);  
  90.     // print actual element  
  91.     cout << *pos << endl;  
  92.     // step one element backward  
  93.     cout<<endl<<"after advance (pos, -1)\n";  
  94.   
  95.     advance (pos, -1);  
  96.     // print actual element  
  97.     cout << *pos << endl;  
  98. }  
  99. /******************************************** 
  100. 运行结果: 
  101. print the list as follow: 
  102. 2007 2008 2009 2010 2011 2012 2013 2014 
  103.  
  104. 2007 
  105.  
  106. after advance (pos, 3) 
  107. 2010 
  108.  
  109. after advance (pos, -1) 
  110. 2009 
  111. *********************************************/  
  112. void test_distance()  
  113. {  
  114.     list<int> coll;  
  115.   
  116.     // insert elements from -3 to 9  
  117.     for (int i=2007; i<=2014; ++i)  
  118.     {  
  119.         coll.push_back(i);  
  120.     }  
  121.     print(coll,"print the list as follow:\n");  
  122.   
  123.     // search element with value 2010  
  124.     list<int>::iterator pos;  
  125.     pos = find (coll.begin(), coll.end(),    // range  
  126.                 2010);                          // value  
  127.   
  128.     if (pos != coll.end())  
  129.     {  
  130.         // process and print difference from the beginning  
  131.         cout << "difference between beginning and 2010: "  
  132.              << distance(coll.begin(),pos) << endl;  
  133.     }  
  134.     else  
  135.     {  
  136.         cout << "2010 not found" << endl;  
  137.     }  
  138. }  
  139. /******************************************** 
  140. 运行结果: 
  141. print the list as follow: 
  142. 2007 2008 2009 2010 2011 2012 2013 2014 
  143. difference between beginning and 2010: 3 
  144. *********************************************/  
  145. void test_iter_swap()  
  146. {  
  147.     list<int> coll;  
  148.   
  149.     // insert elements from 1 to 9  
  150.     for (int i=2007; i<=2014; ++i)  
  151.     {  
  152.         coll.push_back(i);  
  153.     }  
  154.   
  155.     print(coll,"print list as follow:\n");  
  156.   
  157.     // swap first and second value  
  158.     iter_swap (coll.begin(), ++coll.begin());  
  159.   
  160.     print(coll,"after iter_swap (coll.begin(), ++coll.begin()) \n");  
  161.   
  162.     // swap first and last value  
  163.     iter_swap (coll.begin(), --coll.end());  
  164.     print(coll,"after iter_swap (coll.begin(), --coll.end()) \n");  
  165. }  
  166. /******************************************** 
  167. 运行结果: 
  168. print list as follow: 
  169. 2007 2008 2009 2010 2011 2012 2013 2014 
  170. after iter_swap (coll.begin(), ++coll.begin()) 
  171. 2008 2007 2009 2010 2011 2012 2013 2014 
  172. after iter_swap (coll.begin(), --coll.end()) 
  173. 2014 2007 2009 2010 2011 2012 2013 2008 
  174. *********************************************/  
  175. void print_element (int elem)  
  176. {  
  177.     cout << elem << ' ';  
  178. }  
  179.   
  180. void test_reverse_iterator()  
  181. {  
  182.     list<int> coll;  
  183.   
  184.     // insert elements from 1937 to 1945  
  185.     for (int i=1937; i<=1945; ++i)  
  186.     {  
  187.         coll.push_back(i);  
  188.     }  
  189.     cout<<"print all elements in normal order:\n";  
  190.   
  191.     for_each (coll.begin(), coll.end(),      // range  
  192.               print_element);                        // operation  
  193.     cout << endl;  
  194.   
  195.     cout<<"print all elements in reverse order:\n";  
  196.     for_each (coll.rbegin(), coll.rend(),    // range  
  197.               print_element);                        // operations  
  198.     cout << endl;  
  199.     // find position of element with value 1938  
  200.     list<int>::iterator pos1;  
  201.     cout<<"find [1938,1942):\n";  
  202.     pos1 = find (coll.begin(), coll.end(),    // range  
  203.                  1938);                          // value  
  204.   
  205.     cout<<"pos1 is :"<<*pos1<<endl;  
  206.     list<int>::reverse_iterator rpos1(pos1);  
  207.     cout<<"rpos1 is :"<<*rpos1<<endl;  
  208.     cout<<"rpos1.base() is "<<*rpos1.base()<<endl;  
  209.   
  210.     // find position of element with value 1942  
  211.     list<int>::iterator pos2;  
  212.     pos2 = find (coll.begin(), coll.end(),    // range  
  213.                  1942);                          // value  
  214.   
  215.     cout<<"pos2 is :"<<*pos2<<endl;  
  216.     list<int>::reverse_iterator rpos2(pos2);  
  217.     cout<<"rpos2 is :"<<*rpos2<<endl;  
  218.     cout<<"rpos2.base() is "<<*rpos2.base()<<endl;  
  219.   
  220.     // print all elements in range [pos1,pos2)  
  221.     for_each (pos1, pos2,     // range  
  222.               print_element);         // operation  
  223.     cout << endl;  
  224.   
  225.     cout<<"reverse [1938,1942):\n";  
  226.     // print all elements in range [pos1,pos2) in reverse order  
  227.     for_each (rpos2, rpos1,   // range  
  228.               print_element);         // operation  
  229.     cout << endl;  
  230. }  
  231. /******************************************** 
  232. 运行结果: 
  233. print all elements in normal order: 
  234. 1937 1938 1939 1940 1941 1942 1943 1944 1945 
  235. print all elements in reverse order: 
  236. 1945 1944 1943 1942 1941 1940 1939 1938 1937 
  237. find [1938,1942): 
  238. pos1 is :1938 
  239. rpos1 is :1937 
  240. rpos1.base() is 1938 
  241. pos2 is :1942 
  242. rpos2 is :1941 
  243. rpos2.base() is 1942 
  244. 1938 1939 1940 1941 
  245. reverse [1938,1942): 
  246. 1941 1940 1939 1938 
  247.  
  248. *********************************************/  
  249. int main()  
  250. {  
  251.     return 0;  
  252. }  



<iterator>

Iterator definitions
An iterator is any object that, pointing to some element in a range of elements (such as an array or a container), has the ability to iterate through the elements of that range using a set of operators (with at least the increment (++) and dereference (*) operators).

The most obvious form of iterator is a pointer: A pointer can point to elements in an array, and can iterate through them using the increment operator (++). But other kinds of iterators are possible. For example, each container type (such as alist) has a specific iterator type designed to iterate through its elements.

Notice that while a pointer is a form of iterator, not all iterators have the same functionality of pointers; Depending on the properties supported by iterators, they are classified into five different categories:

Iterator categories

Iterators are classified into five categories depending on the functionality they implement:



Input and output iterators are the most limited types of iterators: they can perform sequential single-pass input or output operations.


Forward iterators have all the functionality of input iterators and if they are not constant iterators- also the functionality of output iterators, although they are limited to one direction in which to iterate through a range (forward). All standard containers support at least forward iterator types.

Bidirectional iterators are like forward iterators but can also be iterated through backwards.

Random-access iterators implement all the functionality of bidirectional iterators, and also have the ability to access ranges non-sequentially: distant elements can be accessed directly by applying an offset value to an iterator without iterating through all the elements in between. These iterators have a similar functionality to standard pointers (pointers are iterators of this category).

The properties of each iterator category are:

categorypropertiesvalid expressions
all categoriescopy-constructiblecopy-assignable and destructibleX b(a);
b = a;
Can be incremented++a
a++
Random AccessBidirectionalForwardInputSupports equality/inequality comparisonsa == b
a != b
Can be dereferenced as an rvalue*a
a->m
OutputCan be dereferenced as an lvalue 
(only for mutable iterator types)
*a = t
*a++ = t

default-constructibleX a;
X()
Multi-pass: neither dereferencing nor incrementing affects dereferenceability{ b=a; *a++; *b; }

Can be decremented--a
a--
*a--

Supports arithmetic operators + and -a + n
n + a
a - n
a - b
Supports inequality comparisons (<><= and >=) between iteratorsa < b
a > b
a <= b
a >= b
Supports compound assignment operations += and -=a += n
a -= n
Supports offset dereference operator ([])a[n]

Where X is an iterator type, a and b are objects of this iterator type, t is an object of the type pointed by the iterator type, and n is an integer value.


Functions

Iterator operations:

Iterator generators:

Classes


Predefined iterators


  1. #include <vector>  
  2. #include <iostream>  
  3. #include <list>  
  4. #include <algorithm>  
  5. #include <iterator> //copy  
  6. using namespace std;  
  7.   
  8. template <class T>  
  9. inline void print (const T& coll, const char* optcstr="")  
  10. {  
  11.     typename T::const_iterator pos;  
  12.   
  13.     std::cout << optcstr;  
  14.     for (pos=coll.begin(); pos!=coll.end(); ++pos)  
  15.     {  
  16.         std::cout << *pos << ' ';  
  17.     }  
  18.     std::cout << std::endl;  
  19. }  
  20.   
  21. void  test_random_access_iterator()  
  22. {  
  23.    vector<int> coll;  
  24.     // insert elements from 1991 to 2013  
  25.    for (int i=1991; i<=2013; ++i)  
  26.    {  
  27.        coll.push_back (i);  
  28.    }  
  29.   
  30.    /* print number of elements by processing the distance between beginning and end 
  31.     * - NOTE: uses operator - for iterators 
  32.     */  
  33.    cout << "number/distance: " << coll.end()-coll.begin() << endl;  
  34.   
  35.    /* print all elements 
  36.     * - NOTE: uses operator < instead of operator != 
  37.     */  
  38.    vector<int>::iterator pos;  
  39.    for (pos=coll.begin(); pos<coll.end(); ++pos)  
  40.    {  
  41.        cout << *pos << ' ';  
  42.    }  
  43.    cout << endl;  
  44.   
  45.    /* print all elements 
  46.     * - NOTE: uses operator [] instead of operator * 
  47.     */  
  48.    for (int i=0; i<coll.size(); ++i)  
  49.    {  
  50.        //cout << coll.begin()[i] << ' '; 和如下语句效果相同  
  51.        cout << coll[i] << ' ';  
  52.    }  
  53.    cout << endl;  
  54.   
  55.    /* print every second element 
  56.     * - NOTE: uses operator += 
  57.     */  
  58.    for (pos = coll.begin(); pos < coll.end()-1; pos += 2)  
  59.    {  
  60.        cout << *pos << ' ';  
  61.    }  
  62.    cout << endl;  
  63. }  
  64. /******************************************** 
  65. 运行结果: 
  66. number/distance: 23 
  67. 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 
  68. 2007 2008 2009 2010 2011 2012 2013 
  69. 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 
  70. 2007 2008 2009 2010 2011 2012 2013 
  71. 1991 1993 1995 1997 1999 2001 2003 2005 2007 2009 2011 
  72. *********************************************/  
  73. void test_advance()  
  74. {  
  75.     list<int> coll;  
  76.     // insert elements from 1 to 9  
  77.     for (int i=2007; i<=2014; ++i)  
  78.     {  
  79.         coll.push_back(i);  
  80.     }  
  81.     //打印整个链表  
  82.     print(coll,"print the list as follow:\n");  
  83.     list<int>::iterator pos = coll.begin();  
  84.     // print actual element  
  85.     cout<<endl;  
  86.     cout << *pos << endl;  
  87.     // step three elements forward  
  88.     cout<<endl<<"after advance (pos, 3)\n";  
  89.     advance (pos, 3);  
  90.     // print actual element  
  91.     cout << *pos << endl;  
  92.     // step one element backward  
  93.     cout<<endl<<"after advance (pos, -1)\n";  
  94.   
  95.     advance (pos, -1);  
  96.     // print actual element  
  97.     cout << *pos << endl;  
  98. }  
  99. /******************************************** 
  100. 运行结果: 
  101. print the list as follow: 
  102. 2007 2008 2009 2010 2011 2012 2013 2014 
  103.  
  104. 2007 
  105.  
  106. after advance (pos, 3) 
  107. 2010 
  108.  
  109. after advance (pos, -1) 
  110. 2009 
  111. *********************************************/  
  112. void test_distance()  
  113. {  
  114.     list<int> coll;  
  115.   
  116.     // insert elements from -3 to 9  
  117.     for (int i=2007; i<=2014; ++i)  
  118.     {  
  119.         coll.push_back(i);  
  120.     }  
  121.     print(coll,"print the list as follow:\n");  
  122.   
  123.     // search element with value 2010  
  124.     list<int>::iterator pos;  
  125.     pos = find (coll.begin(), coll.end(),    // range  
  126.                 2010);                          // value  
  127.   
  128.     if (pos != coll.end())  
  129.     {  
  130.         // process and print difference from the beginning  
  131.         cout << "difference between beginning and 2010: "  
  132.              << distance(coll.begin(),pos) << endl;  
  133.     }  
  134.     else  
  135.     {  
  136.         cout << "2010 not found" << endl;  
  137.     }  
  138. }  
  139. /******************************************** 
  140. 运行结果: 
  141. print the list as follow: 
  142. 2007 2008 2009 2010 2011 2012 2013 2014 
  143. difference between beginning and 2010: 3 
  144. *********************************************/  
  145. void test_iter_swap()  
  146. {  
  147.     list<int> coll;  
  148.   
  149.     // insert elements from 1 to 9  
  150.     for (int i=2007; i<=2014; ++i)  
  151.     {  
  152.         coll.push_back(i);  
  153.     }  
  154.   
  155.     print(coll,"print list as follow:\n");  
  156.   
  157.     // swap first and second value  
  158.     iter_swap (coll.begin(), ++coll.begin());  
  159.   
  160.     print(coll,"after iter_swap (coll.begin(), ++coll.begin()) \n");  
  161.   
  162.     // swap first and last value  
  163.     iter_swap (coll.begin(), --coll.end());  
  164.     print(coll,"after iter_swap (coll.begin(), --coll.end()) \n");  
  165. }  
  166. /******************************************** 
  167. 运行结果: 
  168. print list as follow: 
  169. 2007 2008 2009 2010 2011 2012 2013 2014 
  170. after iter_swap (coll.begin(), ++coll.begin()) 
  171. 2008 2007 2009 2010 2011 2012 2013 2014 
  172. after iter_swap (coll.begin(), --coll.end()) 
  173. 2014 2007 2009 2010 2011 2012 2013 2008 
  174. *********************************************/  
  175. void print_element (int elem)  
  176. {  
  177.     cout << elem << ' ';  
  178. }  
  179.   
  180. void test_reverse_iterator()  
  181. {  
  182.     list<int> coll;  
  183.   
  184.     // insert elements from 1937 to 1945  
  185.     for (int i=1937; i<=1945; ++i)  
  186.     {  
  187.         coll.push_back(i);  
  188.     }  
  189.     cout<<"print all elements in normal order:\n";  
  190.   
  191.     for_each (coll.begin(), coll.end(),      // range  
  192.               print_element);                        // operation  
  193.     cout << endl;  
  194.   
  195.     cout<<"print all elements in reverse order:\n";  
  196.     for_each (coll.rbegin(), coll.rend(),    // range  
  197.               print_element);                        // operations  
  198.     cout << endl;  
  199.     // find position of element with value 1938  
  200.     list<int>::iterator pos1;  
  201.     cout<<"find [1938,1942):\n";  
  202.     pos1 = find (coll.begin(), coll.end(),    // range  
  203.                  1938);                          // value  
  204.   
  205.     cout<<"pos1 is :"<<*pos1<<endl;  
  206.     list<int>::reverse_iterator rpos1(pos1);  
  207.     cout<<"rpos1 is :"<<*rpos1<<endl;  
  208.     cout<<"rpos1.base() is "<<*rpos1.base()<<endl;  
  209.   
  210.     // find position of element with value 1942  
  211.     list<int>::iterator pos2;  
  212.     pos2 = find (coll.begin(), coll.end(),    // range  
  213.                  1942);                          // value  
  214.   
  215.     cout<<"pos2 is :"<<*pos2<<endl;  
  216.     list<int>::reverse_iterator rpos2(pos2);  
  217.     cout<<"rpos2 is :"<<*rpos2<<endl;  
  218.     cout<<"rpos2.base() is "<<*rpos2.base()<<endl;  
  219.   
  220.     // print all elements in range [pos1,pos2)  
  221.     for_each (pos1, pos2,     // range  
  222.               print_element);         // operation  
  223.     cout << endl;  
  224.   
  225.     cout<<"reverse [1938,1942):\n";  
  226.     // print all elements in range [pos1,pos2) in reverse order  
  227.     for_each (rpos2, rpos1,   // range  
  228.               print_element);         // operation  
  229.     cout << endl;  
  230. }  
  231. /******************************************** 
  232. 运行结果: 
  233. print all elements in normal order: 
  234. 1937 1938 1939 1940 1941 1942 1943 1944 1945 
  235. print all elements in reverse order: 
  236. 1945 1944 1943 1942 1941 1940 1939 1938 1937 
  237. find [1938,1942): 
  238. pos1 is :1938 
  239. rpos1 is :1937 
  240. rpos1.base() is 1938 
  241. pos2 is :1942 
  242. rpos2 is :1941 
  243. rpos2.base() is 1942 
  244. 1938 1939 1940 1941 
  245. reverse [1938,1942): 
  246. 1941 1940 1939 1938 
  247.  
  248. *********************************************/  
  249. int main()  
  250. {  
  251.     return 0;  
  252. }  

std::advance

template <class InputIterator, class Distance>
  void advance (InputIterator& it, Distance n);
Advance iterator
Advances the iterator   it   by   n   element positions.

If   it   is a   random-access iterator , the function uses just once   operator+   or   operator- . Otherwise, the function uses repeatedly the increase or decrease operator ( operator++   or   operator-- ) until   n   elements have been advanced.

Parameters

it
Iterator to be advanced.
InputIterator shall be at least an  input iterator.
n
Number of element positions to advance.
This shall only be negative for  random-access and  bidirectional iterators.
Distance shall be a numerical type able to represent distances between iterators of this type.

Return value

none


std::distance

template<class InputIterator>
  typename iterator_traits<InputIterator>::difference_type
    distance (InputIterator first, InputIterator last);
Return distance between iterators
Calculates the number of elements between   first   and   last .

If   it   is a   random-access iterator , the function uses   operator-   to calculate this. Otherwise, the function uses the increase operator ( operator++ ) repeatedly.

Parameters

first
Iterator pointing to the initial element.
last
Iterator pointing to the final element. This must be reachable from  first.
InputIterator   shall be at least an   input iterator .

Return value

The number of elements between   first   and   last .


Summary
The Good
  • The STL provides iterators as a convenient abstraction for accessing many different types of containers.
  • Iterators for templated classes are generated inside the class scope with the syntax
    <em>class_name</em><<em>parameters</em>>::iterator
    
  • Iterators can be thought of as limited pointers (or, in the case of random access iterators, as nearly equivalent to pointers)
The Gotchas
  • Iterators do not provide bounds checking; it is possible to overstep the bounds of a container, resulting in segmentation faults
  • Different containers support different iterators, so it is not always possible to change the underlying container type without making changes to your code
  • Iterators can be invalidated if the underlying container (the container being iterated over) is changed significantly





FROM:  http://blog.csdn.net/wangshihui512/article/details/8940552

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值