#include <vector>
#include <iostream>
#include <list>
#include <algorithm>
#include <iterator> //copy
using namespace std;
template <class T>
inline void print (const T& coll, const char* optcstr="")
{
typename T::const_iterator pos;
std::cout << optcstr;
for (pos=coll.begin(); pos!=coll.end(); ++pos)
{
std::cout << *pos << ' ';
}
std::cout << std::endl;
}
void test_random_access_iterator()
{
vector<int> coll;
// insert elements from 1991 to 2013
for (int i=1991; i<=2013; ++i)
{
coll.push_back (i);
}
/* print number of elements by processing the distance between beginning and end
* - NOTE: uses operator - for iterators
*/
cout << "number/distance: " << coll.end()-coll.begin() << endl;
/* print all elements
* - NOTE: uses operator < instead of operator !=
*/
vector<int>::iterator pos;
for (pos=coll.begin(); pos<coll.end(); ++pos)
{
cout << *pos << ' ';
}
cout << endl;
/* print all elements
* - NOTE: uses operator [] instead of operator *
*/
for (int i=0; i<coll.size(); ++i)
{
//cout << coll.begin()[i] << ' '; 和如下语句效果相同
cout << coll[i] << ' ';
}
cout << endl;
/* print every second element
* - NOTE: uses operator +=
*/
for (pos = coll.begin(); pos < coll.end()-1; pos += 2)
{
cout << *pos << ' ';
}
cout << endl;
}
/********************************************
运行结果:
number/distance: 23
1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006
2007 2008 2009 2010 2011 2012 2013
1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006
2007 2008 2009 2010 2011 2012 2013
1991 1993 1995 1997 1999 2001 2003 2005 2007 2009 2011
*********************************************/
void test_advance()
{
list<int> coll;
// insert elements from 1 to 9
for (int i=2007; i<=2014; ++i)
{
coll.push_back(i);
}
//打印整个链表
print(coll,"print the list as follow:\n");
list<int>::iterator pos = coll.begin();
// print actual element
cout<<endl;
cout << *pos << endl;
// step three elements forward
cout<<endl<<"after advance (pos, 3)\n";
advance (pos, 3);
// print actual element
cout << *pos << endl;
// step one element backward
cout<<endl<<"after advance (pos, -1)\n";
advance (pos, -1);
// print actual element
cout << *pos << endl;
}
/********************************************
运行结果:
print the list as follow:
2007 2008 2009 2010 2011 2012 2013 2014
2007
after advance (pos, 3)
2010
after advance (pos, -1)
2009
*********************************************/
void test_distance()
{
list<int> coll;
// insert elements from -3 to 9
for (int i=2007; i<=2014; ++i)
{
coll.push_back(i);
}
print(coll,"print the list as follow:\n");
// search element with value 2010
list<int>::iterator pos;
pos = find (coll.begin(), coll.end(), // range
2010); // value
if (pos != coll.end())
{
// process and print difference from the beginning
cout << "difference between beginning and 2010: "
<< distance(coll.begin(),pos) << endl;
}
else
{
cout << "2010 not found" << endl;
}
}
/********************************************
运行结果:
print the list as follow:
2007 2008 2009 2010 2011 2012 2013 2014
difference between beginning and 2010: 3
*********************************************/
void test_iter_swap()
{
list<int> coll;
// insert elements from 1 to 9
for (int i=2007; i<=2014; ++i)
{
coll.push_back(i);
}
print(coll,"print list as follow:\n");
// swap first and second value
iter_swap (coll.begin(), ++coll.begin());
print(coll,"after iter_swap (coll.begin(), ++coll.begin()) \n");
// swap first and last value
iter_swap (coll.begin(), --coll.end());
print(coll,"after iter_swap (coll.begin(), --coll.end()) \n");
}
/********************************************
运行结果:
print list as follow:
2007 2008 2009 2010 2011 2012 2013 2014
after iter_swap (coll.begin(), ++coll.begin())
2008 2007 2009 2010 2011 2012 2013 2014
after iter_swap (coll.begin(), --coll.end())
2014 2007 2009 2010 2011 2012 2013 2008
*********************************************/
void print_element (int elem)
{
cout << elem << ' ';
}
void test_reverse_iterator()
{
list<int> coll;
// insert elements from 1937 to 1945
for (int i=1937; i<=1945; ++i)
{
coll.push_back(i);
}
cout<<"print all elements in normal order:\n";
for_each (coll.begin(), coll.end(), // range
print_element); // operation
cout << endl;
cout<<"print all elements in reverse order:\n";
for_each (coll.rbegin(), coll.rend(), // range
print_element); // operations
cout << endl;
// find position of element with value 1938
list<int>::iterator pos1;
cout<<"find [1938,1942):\n";
pos1 = find (coll.begin(), coll.end(), // range
1938); // value
cout<<"pos1 is :"<<*pos1<<endl;
list<int>::reverse_iterator rpos1(pos1);
cout<<"rpos1 is :"<<*rpos1<<endl;
cout<<"rpos1.base() is "<<*rpos1.base()<<endl;
// find position of element with value 1942
list<int>::iterator pos2;
pos2 = find (coll.begin(), coll.end(), // range
1942); // value
cout<<"pos2 is :"<<*pos2<<endl;
list<int>::reverse_iterator rpos2(pos2);
cout<<"rpos2 is :"<<*rpos2<<endl;
cout<<"rpos2.base() is "<<*rpos2.base()<<endl;
// print all elements in range [pos1,pos2)
for_each (pos1, pos2, // range
print_element); // operation
cout << endl;
cout<<"reverse [1938,1942):\n";
// print all elements in range [pos1,pos2) in reverse order
for_each (rpos2, rpos1, // range
print_element); // operation
cout << endl;
}
/********************************************
运行结果:
print all elements in normal order:
1937 1938 1939 1940 1941 1942 1943 1944 1945
print all elements in reverse order:
1945 1944 1943 1942 1941 1940 1939 1938 1937
find [1938,1942):
pos1 is :1938
rpos1 is :1937
rpos1.base() is 1938
pos2 is :1942
rpos2 is :1941
rpos2.base() is 1942
1938 1939 1940 1941
reverse [1938,1942):
1941 1940 1939 1938
*********************************************/
int main()
{
return 0;
}
<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:
category | properties | valid expressions | |||
---|---|---|---|---|---|
all categories | copy-constructible, copy-assignable and destructible | X b(a); |
|||
Can be incremented | ++a |
||||
Random Access | Bidirectional | Forward | Input | Supports equality/inequality comparisons | a == b |
Can be dereferenced as an rvalue | *a a->m |
||||
Output | Can be dereferenced as an lvalue (only for mutable iterator types) |
*a = t *a++ = t |
|||
default-constructible | X 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 iterators | a < 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:- advance
- Advance iterator (function template )
- distance
- Return distance between iterators (function template )
- begin
- Iterator to beginning (function template )
- end
- Iterator to end (function template )
- prev
- Get iterator to previous element (function template )
- next
- Get iterator to next element (function template )
Iterator generators:
- back_inserter
- Construct back insert iterator (function template )
- front_inserter
- Constructs front insert iterator (function template )
- inserter
- Construct insert iterator (function template )
- make_move_iterator
- Construct move iterator (function template )
Classes
- iterator
- Iterator base class (class template )
- iterator_traits
- Iterator traits (class template )
Predefined iterators
- reverse_iterator
- Reverse iterator (class template )
- move_iterator
- Move iterator (class template )
- back_insert_iterator
- Back insert iterator (class template )
- front_insert_iterator
- Front insert iterator (class template )
- insert_iterator
- Insert iterator (class template )
- istream_iterator
- Istream iterator (class template )
- ostream_iterator
- Ostream iterator (class template )
- istreambuf_iterator
- Input stream buffer iterator (class template )
- ostreambuf_iterator
- Output stream buffer iterator (class template )
#include <vector>
#include <iostream>
#include <list>
#include <algorithm>
#include <iterator> //copy
using namespace std;
template <class T>
inline void print (const T& coll, const char* optcstr="")
{
typename T::const_iterator pos;
std::cout << optcstr;
for (pos=coll.begin(); pos!=coll.end(); ++pos)
{
std::cout << *pos << ' ';
}
std::cout << std::endl;
}
void test_random_access_iterator()
{
vector<int> coll;
// insert elements from 1991 to 2013
for (int i=1991; i<=2013; ++i)
{
coll.push_back (i);
}
/* print number of elements by processing the distance between beginning and end
* - NOTE: uses operator - for iterators
*/
cout << "number/distance: " << coll.end()-coll.begin() << endl;
/* print all elements
* - NOTE: uses operator < instead of operator !=
*/
vector<int>::iterator pos;
for (pos=coll.begin(); pos<coll.end(); ++pos)
{
cout << *pos << ' ';
}
cout << endl;
/* print all elements
* - NOTE: uses operator [] instead of operator *
*/
for (int i=0; i<coll.size(); ++i)
{
//cout << coll.begin()[i] << ' '; 和如下语句效果相同
cout << coll[i] << ' ';
}
cout << endl;
/* print every second element
* - NOTE: uses operator +=
*/
for (pos = coll.begin(); pos < coll.end()-1; pos += 2)
{
cout << *pos << ' ';
}
cout << endl;
}
/********************************************
运行结果:
number/distance: 23
1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006
2007 2008 2009 2010 2011 2012 2013
1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006
2007 2008 2009 2010 2011 2012 2013
1991 1993 1995 1997 1999 2001 2003 2005 2007 2009 2011
*********************************************/
void test_advance()
{
list<int> coll;
// insert elements from 1 to 9
for (int i=2007; i<=2014; ++i)
{
coll.push_back(i);
}
//打印整个链表
print(coll,"print the list as follow:\n");
list<int>::iterator pos = coll.begin();
// print actual element
cout<<endl;
cout << *pos << endl;
// step three elements forward
cout<<endl<<"after advance (pos, 3)\n";
advance (pos, 3);
// print actual element
cout << *pos << endl;
// step one element backward
cout<<endl<<"after advance (pos, -1)\n";
advance (pos, -1);
// print actual element
cout << *pos << endl;
}
/********************************************
运行结果:
print the list as follow:
2007 2008 2009 2010 2011 2012 2013 2014
2007
after advance (pos, 3)
2010
after advance (pos, -1)
2009
*********************************************/
void test_distance()
{
list<int> coll;
// insert elements from -3 to 9
for (int i=2007; i<=2014; ++i)
{
coll.push_back(i);
}
print(coll,"print the list as follow:\n");
// search element with value 2010
list<int>::iterator pos;
pos = find (coll.begin(), coll.end(), // range
2010); // value
if (pos != coll.end())
{
// process and print difference from the beginning
cout << "difference between beginning and 2010: "
<< distance(coll.begin(),pos) << endl;
}
else
{
cout << "2010 not found" << endl;
}
}
/********************************************
运行结果:
print the list as follow:
2007 2008 2009 2010 2011 2012 2013 2014
difference between beginning and 2010: 3
*********************************************/
void test_iter_swap()
{
list<int> coll;
// insert elements from 1 to 9
for (int i=2007; i<=2014; ++i)
{
coll.push_back(i);
}
print(coll,"print list as follow:\n");
// swap first and second value
iter_swap (coll.begin(), ++coll.begin());
print(coll,"after iter_swap (coll.begin(), ++coll.begin()) \n");
// swap first and last value
iter_swap (coll.begin(), --coll.end());
print(coll,"after iter_swap (coll.begin(), --coll.end()) \n");
}
/********************************************
运行结果:
print list as follow:
2007 2008 2009 2010 2011 2012 2013 2014
after iter_swap (coll.begin(), ++coll.begin())
2008 2007 2009 2010 2011 2012 2013 2014
after iter_swap (coll.begin(), --coll.end())
2014 2007 2009 2010 2011 2012 2013 2008
*********************************************/
void print_element (int elem)
{
cout << elem << ' ';
}
void test_reverse_iterator()
{
list<int> coll;
// insert elements from 1937 to 1945
for (int i=1937; i<=1945; ++i)
{
coll.push_back(i);
}
cout<<"print all elements in normal order:\n";
for_each (coll.begin(), coll.end(), // range
print_element); // operation
cout << endl;
cout<<"print all elements in reverse order:\n";
for_each (coll.rbegin(), coll.rend(), // range
print_element); // operations
cout << endl;
// find position of element with value 1938
list<int>::iterator pos1;
cout<<"find [1938,1942):\n";
pos1 = find (coll.begin(), coll.end(), // range
1938); // value
cout<<"pos1 is :"<<*pos1<<endl;
list<int>::reverse_iterator rpos1(pos1);
cout<<"rpos1 is :"<<*rpos1<<endl;
cout<<"rpos1.base() is "<<*rpos1.base()<<endl;
// find position of element with value 1942
list<int>::iterator pos2;
pos2 = find (coll.begin(), coll.end(), // range
1942); // value
cout<<"pos2 is :"<<*pos2<<endl;
list<int>::reverse_iterator rpos2(pos2);
cout<<"rpos2 is :"<<*rpos2<<endl;
cout<<"rpos2.base() is "<<*rpos2.base()<<endl;
// print all elements in range [pos1,pos2)
for_each (pos1, pos2, // range
print_element); // operation
cout << endl;
cout<<"reverse [1938,1942):\n";
// print all elements in range [pos1,pos2) in reverse order
for_each (rpos2, rpos1, // range
print_element); // operation
cout << endl;
}
/********************************************
运行结果:
print all elements in normal order:
1937 1938 1939 1940 1941 1942 1943 1944 1945
print all elements in reverse order:
1945 1944 1943 1942 1941 1940 1939 1938 1937
find [1938,1942):
pos1 is :1938
rpos1 is :1937
rpos1.base() is 1938
pos2 is :1942
rpos2 is :1941
rpos2.base() is 1942
1938 1939 1940 1941
reverse [1938,1942):
1941 1940 1939 1938
*********************************************/
int main()
{
return 0;
}
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
nonestd::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.
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
class_name<parameters>::iterator
- Iterators can be thought of as limited pointers (or, in the case of random access iterators, as nearly equivalent to pointers)
- 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