The program examples for the member used functions compiled usingVC++7.0 / .Net, win32 empty console mode application. This is a continuation from the previous Module.Linuxg++ compilation examples given at the end of this Module. The source code for this tutorial is available inC++ STL Iterator source code samples.
| The reverse_iterator Template Class
template<class Iterator>
Parameter
&*(reverse_iterator (i)) == &*(i – 1)
|
Typedef | Description |
difference_type | A type that provides the difference between two reverse_iterators referring to elements within the same container. |
iterator_type | A type that provides the underlying iterator for a reverse_iterator. |
pointer | A type that provides a pointer to an element addressed by a reverse_iterator. |
reference | A type that provides a reference to an element addressed by a reverse_iterator. |
Table 32.25 |
Returns a reference to an element offset from the element addressed by areverse_iterator by a specified number of positions.
reference operator[](difference_type _Off) const;
Parameter | Description |
_Off | The offset from thereverse_iterator address. |
Table 32.26 |
The return value is the reference to the element offset.
The operator returns *(*this + _Off).
// reverse_iterator, operator[ ]
#include <iterator>
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
int main()
{
int i;
vector<int> vec;
for(i = 10; i<=17; ++i)
vec.push_back(i);
cout<<"Normal....\n";
vector <int>::iterator vIter;
cout<<"The vector vec data: ";
for(vIter = vec.begin(); vIter != vec.end(); vIter++)
cout<<*vIter<<" ";
cout<<endl;
cout<<"\nReverse....\n";
vector <int>::reverse_iterator rvIter;
cout<<"The vector vec reversed data: ";
for(rvIter = vec.rbegin(); rvIter != vec.rend(); rvIter++)
cout<<*rvIter<<" ";
cout<<endl;
cout<<"\nFinding data, 15....\n";
cout<<"Operation: pos = find(vec.begin(), vec.end(), 15)\n";
vector <int>::iterator pos;
pos = find(vec.begin(), vec.end(), 15);
cout<<"The iterator pos points to: "<<*pos<<endl;
reverse_iterator<vector<int>::iterator> rpos(pos);
// declare a difference type for a parameter
reverse_iterator<vector<int>::iterator>::difference_type diff = 3;
cout<<"\nOperation: rpos(pos)\n";
cout<<"The iterator rpos points to: "<<*rpos<<endl;
// declare a reference return type & use operator[ ]
cout<<"\nOperation: refrpos = rpos[diff], where diff = 3\n";
reverse_iterator<vector<int>::iterator>::reference refrpos = rpos[diff];
cout<<"The iterator rpos now points to: "<<refrpos<<endl;
return 0;
}
A type that provides a pointer to an element addressed by areverse_iterator.
typedef typename iterator_traits<Iterator>::pointer pointer;
The type is a synonym for the iterator trait typename iterator_traits<Random-access iterator>::pointer.
// reverse_iterator, pointer
#include <iterator>
#include <algorithm>
#include <vector>
#include <utility>
#include <iostream>
using namespace std;
int main()
{
typedef vector<pair<int, int> > pVector;
pVector vec;
vec.push_back(pVector::value_type(1, 2));
vec.push_back(pVector::value_type(3, 4));
vec.push_back(pVector::value_type(5, 6));
pVector::iterator pvIter;
cout<<"Operation: pvIter->first and pvIter->second\n";
cout<<"The vector vec of integer pairs is: \n";
for(pvIter = vec.begin(); pvIter != vec.end(); pvIter++)
cout<<pvIter->first<<", "<<pvIter->second<<endl;
pVector::reverse_iterator rpvIter;
cout<<"\nOperation: reverse rpvIter->first and rpvIter->second";
cout<<"\nThe vector vec reversed is: \n";
for(rpvIter = vec.rbegin(); rpvIter != vec.rend(); rpvIter++)
cout<<rpvIter->first<< ", " <<rpvIter->second<<endl;
cout<<"\nOperation: pos = vec.begin() then pos++...";
pVector::iterator pos = vec.begin();
pos++;
cout<<"\nThe iterator pos points to:\n"<<pos->first<< ", " <<pos->second<<endl;
cout<<"\nOperation: reverse, rpos(pos)";
pVector::reverse_iterator rpos(pos);
cout<<"\nThe iterator rpos points to:\n"<<rpos->first<< ", " <<rpos->second<<endl;
return 0;
}
Member function | Description |
base() | Recovers the underlying iterator from its reverse_iterator. |
reverse_iterator | Constructs a default reverse_iterator or a reverse_iterator from an underlying iterator. |
Table 32.27 |
Recovers the underlying iterator from its reverse_iterator.
RandomIterator base() const;
The return value is the iterator underlying the reverse_iterator.
The identity that relates all reverse iterators to their underlying iterators is:
&*(reverse_iterator(i)) == &*(i – 1).
In practice, this means that in the reversed sequence thereverse_iterator will refer to the element one position beyond (to the right of) the element that the iterator had referred to in the original sequence.
So if an iterator addressed the element valued 6 in the sequence (2, 4, 6, 8), then the reverse_iterator will address the element valued 4 in the reversed sequence (8, 6, 4, 2).
// reverse_iterator, base()
#include <iterator>
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
int main()
{
int i;
vector<int> vec;
for(i = 10; i<=15; ++i)
vec.push_back(i);
vector <int>::iterator vIter;
cout<<"The vector vec data: ";
for(vIter = vec.begin(); vIter != vec.end(); vIter++)
cout<<*vIter<<" ";
cout<<endl;
vector<int>::reverse_iterator rvIter;
cout<<"The vector vec reversed data: ";
for(rvIter = vec.rbegin(); rvIter != vec.rend(); rvIter++)
cout<<*rvIter<<" ";
cout<<endl;
cout<<"\nFinding data...";
cout<<"\nOperation: pos = find(vec.begin(), vec.end(), 13)\n";
vector <int>::iterator pos, bpos;
pos = find(vec.begin(), vec.end(), 13);
cout<<"The iterator pos points to: "<<*pos<<endl;
typedef reverse_iterator<vector<int>::iterator>::iterator_type it_vec_int_type;
cout<<"\nFinding data, reverse...\n";
cout<<"Operation: rpos(pos)\n";
reverse_iterator<it_vec_int_type> rpos(pos);
cout<<"The reverse_iterator rpos points to: "<<*rpos<<endl;
bpos = rpos.base();
cout<<"The iterator underlying rpos is bpos & it points to: "<<*bpos<<endl;
return 0;
}
Operator | Description |
operator* | Returns the element that a reverse_iterator addresses. |
operator+ | Adds an offset to an iterator and returns the new reverse_iterator addressing the inserted element at the new offset position. |
operator++ | Increments the reverse_iterator to the next element. |
operator+= | Adds a specified offset from areverse_iterator. |
operator- | Subtracts an offset from a reverse_iterator and returns a reverse_iterator addressing the element at the offset position. |
Operator-- | Decrements the reverse_iterator to the previous element. |
operator-= | Subtracts a specified offset from areverse_iterator. |
operator-> | Returns a pointer to the element addressed by the reverse_iterator. |
operator[ ] | Returns a reference to an element offset from the element addressed by a reverse_iterator by a specified number of positions. |
Table 32.28 |
32.2 The Iterator Adapters
32.2.1 The Insert Iterators
|
Insert iterator | Operation |
back_inserter(container) | Appends in the same order by usingpush_back() |
front_inserter(container) | Inserts at the front in reverse order by using push_front() |
inserter(container, pos) | Inserts at pos(in the same order) by using insert() |
32.29: Predefined insert iterators |
// inserter iterator
#include <iostream>
#include <vector>
#include <deque>
#include <list>
#include <set>
#include <algorithm>
using namespace std;
int main()
{
list<int> lst;
list <int>::iterator lstIter;
// insert elements from 1 to 10 into the lst list
for(int i=1; i<=10; ++i)
lst.push_back(i);
cout<<"Operation: lst.push_back(i)\n";
cout<<"lst data: ";
for(lstIter = lst.begin(); lstIter != lst.end(); lstIter++)
cout<<*lstIter<<' ';
cout<<endl;
// copy the elements of lst list into vec vector by appending them
vector<int> vec;
vector <int>::iterator Iter;
// from source to destination...
copy(lst.begin(), lst.end(), back_inserter(vec));
cout<<"\nOperation: copy(lst.begin(), lst.end(), back_inserter(vec))\n";
cout<<"vec data: ";
for(Iter = vec.begin(); Iter != vec.end(); Iter++)
cout<<*Iter<<" ";
cout<<endl;
// copy the elements of lst list into deq deque by inserting them at the front
// and reverses the order of the elements deque<int> deq;
deque <int>::iterator deqIter;
copy(lst.begin(), lst.end(), front_inserter(deq));
cout<<"\nOperation: copy(lst.begin(), lst.end(), front_inserter(deq))\n";
cout<<"deq data: ";
for(deqIter = deq.begin(); deqIter != deq.end(); deqIter++)
cout<<*deqIter<<" ";
cout<<endl;
// copy elements of lst list into st set only inserter that works for associative collections
set<int> st;
set<int>::iterator stIter;
copy(lst.begin(), lst.end(), inserter(st, st.begin()));
cout<<"\nOperation: copy(lst.begin(), lst.end(), inserter(st, st.begin()))\n";
cout<<"set data: ";
for(stIter = st.begin(); stIter != st.end(); stIter++)
cout<<*stIter<<" ";
cout<<endl;
return 0;
}
The program example uses all three predefined insert iterators as listed below:
Iterator | Description |
Back | Back inserters can be used only for containers that provide push_back() as a member function. In the C++ standard library, these containers are vector, deque, and list. |
Front | Front inserter reverses the order of the inserted elements. If you insert 1 at the front and then 2 at the front, the 1 is after the 2. Front inserters can be used only for containers that provide push_front() as a member function. In the C++ standard library, these containers are deque and list. |
General | A general inserter, also called simply an inserter,inserts elements directly in front of the position that is passed as the second argument of its initialization. It calls theinsert() member function with the new value and the new position as arguments. Note that all predefined containers have such an insert() member function. This is the only predefined inserter for associative containers. |
Table 32.30 |
Another very helpful kind of iterator adapter is a stream iterator. Stream iterators are iterators that read from and write to a stream.
Thus, they provide an abstraction that lets the input from the keyboard behave as a collection, from which you can read. Similarly you can redirect the output of an algorithm directly into a file or onto the screen.
Consider the following example. It is a typical example of the power of the whole STL. Compared with ordinary C or C++, it does a lot of complex processing by using only a few statements. For example study the following example.
// stream iterator
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
vector<string> strvec;
vector <string>::iterator Iter;
// read from the standard input until EOF/error the EOF is platform dependent...
// then copy (inserting) to strvec vector...copy from begin to end of source, to destination
copy(istream_iterator<string>(cin), istream_iterator<string>(), back_inserter(strvec));
cout<<"\nstrvec data: ";
for(Iter = strvec.begin(); Iter != strvec.end(); Iter++)
cout<<*Iter<<" ";
cout<<endl;
// do some sorting
sort(strvec.begin(), strvec.end());
cout<<"\nstrvec data: ";
for(Iter = strvec.begin(); Iter != strvec.end(); Iter++)
cout<<*Iter<<" ";
cout<<"\n\n";
// print all elements without duplicates to standard output
unique_copy(strvec.begin(), strvec.end(), ostream_iterator<string> (cout, "\n"));
return 0;
}
The third kind of predefined iterator adapters are reverse iterators.
Reverse iterators operate in reverse. They switch the call of an increment operator internally into a call of the decrement operator, and vice versa.
All containers can create reverse iterators via their member functionsrbegin() and rend().
// reverse iterator using rbegin() and rend()
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
vector<int> vec;
// insert elements from 1 to 10
for(int i=1; i<=10; ++i)
vec.push_back(i);
// print all element in reverse order
copy(vec.rbegin(), vec.rend(), ostream_iterator<int> (cout," "));
cout<<endl;
return 0;
}
The following is a program example compiled usingg++.
// ******ostreamiterator.cpp********
// ostream_iterator, ostream_iterator
#include <iterator>
#include <vector>
#include <iostream>
using namespace std;
int main()
{
// ostream_iterator for stream cout
ostream_iterator<int> intOut(cout, "\n");
*intOut = 12;
intOut++;
*intOut = 33;
intOut++;
int i;
vector<int> vec;
for(i = 10; i<=15; ++i)
vec.push_back(i);
cout<<"Operation: with and without delimiter...\n";
// write elements to standard output stream
cout<<"Elements output without delimiter: ";
copy(vec.begin(), vec.end(), ostream_iterator<int> (cout));
cout<<endl;
// write elements with delimiter " " to output stream
cout<<"Elements output with delimiter: ";
copy(vec.begin(), vec.end(), ostream_iterator<int> (cout, " "));
cout<<endl;
return 0;
}
[bodo@bakawali ~]$ g++ ostreamiterator.cpp -o ostreamiterator
[bodo@bakawali ~]$ ./ostreamiterator
12
33
Operation: with and without delimiter...
Elements output without delimiter: 101112131415
Elements output with delimiter: 10 11 12 13 14 15
// *****insertiter.cpp******
// inserter iterator
#include <iostream>
#include <vector>
#include <deque>
#include <list>
#include <set>
#include <algorithm>
using namespace std;
int main()
{
list<int> lst;
list <int>::iterator lstIter;
// insert elements from 1 to 10 into the lst list
for(int i=1; i<=10; ++i)
lst.push_back(i);
cout<<"Operation: lst.push_back(i)\n";
cout<<"lst data: ";
for(lstIter = lst.begin(); lstIter != lst.end(); lstIter++)
cout<<*lstIter<<' ';
cout<<endl;
// copy the elements of lst list into vec vector by appending them
vector<int> vec;
vector <int>::iterator Iter;
// from source to destination...
copy(lst.begin(), lst.end(), back_inserter(vec));
cout<<"\nOperation: copy(lst.begin(), lst.end(), back_inserter(vec))\n";
cout<<"vec data: ";
for(Iter = vec.begin(); Iter != vec.end(); Iter++)
cout<<*Iter<<" ";
cout<<endl;
// copy the elements of lst list into deq deque by inserting them at the front and reverses the order of the elements
deque<int> deq;
deque <int>::iterator deqIter;
copy(lst.begin(), lst.end(), front_inserter(deq));
cout<<"\nOperation: copy(lst.begin(), lst.end(), front_inserter(deq))\n";
cout<<"deq data: ";
for(deqIter = deq.begin(); deqIter != deq.end(); deqIter++)
cout<<*deqIter<<" ";
cout<<endl;
// copy elements of lst list into st set only inserter that works for associative collections
set<int> st;
set<int>::iterator stIter;
copy(lst.begin(), lst.end(), inserter(st, st.begin()));
cout<<"\nOperation: copy(lst.begin(), lst.end(), inserter(st, st.begin()))\n";
cout<<"set data: ";
for(stIter = st.begin(); stIter != st.end(); stIter++)
cout<<*stIter<<" ";
cout<<endl;
return 0;
}
[bodo@bakawali ~]$ g++ insertiter.cpp -o insertiter
[bodo@bakawali ~]$ ./insertiter
Operation: lst.push_back(i)
lst data: 1 2 3 4 5 6 7 8 9 10
Operation: copy(lst.begin(), lst.end(), back_inserter(vec))
vec data: 1 2 3 4 5 6 7 8 9 10
Operation: copy(lst.begin(), lst.end(), front_inserter(deq))
deq data: 10 9 8 7 6 5 4 3 2 1
Operation: copy(lst.begin(), lst.end(), inserter(st, st.begin()))
set data: 1 2 3 4 5 6 7 8 9 10
--------------------------------------------End of Iterator--------------------------------------
The source code for this tutorial is available inC++ STL Iterator source code samples.
Acomplete C++ Standard Library documentation that includes STL.