|< C++ STL Iterator 6 | Main | C++ STL Algorithm 1 >| Site Index | Download |


 

 

 

 

 

MODULE 32_2

THE C++ STL ADVANCED ITERATOR PART 7

 

 

 

 

 

My Training Period: xx hours

 

The program examples for the member used functions compiled using VC++7.0 / .Net, win32 empty console mode application.  This is a continuation from the previous Module. Linux g++ compilation examples given at the end of this Module. The source code for this tutorial is available in C++ STL Iterator source code samples.

 

The C++ STL iterators knowledge that supposed to be acquired:

 

 

 

 

 

 

 

 

 

 

 

 

What do we have in this session?

  1. ostreambuf_iterator, failed() program example

  2. The reverse_iterator Template Class

  3. The reverse_iterator Template Class Members

  4. The reverse_iterator::operator[ ]

  5. reverse_iterator, operator[ ] program example

  6. The reverse_iterator::pointer

  7. reverse_iterator, pointer program example

  8. The reverse_iterator::base

  9. reverse_iterator, base() program example

  10. The Iterator Adapters

  11. The Insert Iterators

  12. inserter iterator program example

  13. A Stream Iterators

  14. stream iterator program example

  15. A Reverse Iterators

  16. ostream_iterator, ostream_iterator program example – g++

  17. inserter iterator program example – g++

 

 

 

 

The reverse_iterator Template Class

  • The template class is an iterator adaptor that describes a reverse iterator object that behaves like a random-access or bidirectional iterator, only in reverse.  It enables the backward traversal of a range.

template<class Iterator>

 

Parameter

 

Parameter

Description

Iterator

The type that represents the iterator to be adapted to operate in reverse.

 

Table 32.24

  • Existing STL containers also define reverse_iterator and const_reverse_iterator types and have member functions rbegin() and rend() that return reverse iterators.

  • These iterators have overwritten semantics.  The reverse_iterator adaptor supplements this functionality as offers insert semantics and can also be used with streams.

  • The reverse_iterators that require a bidirectional iterator must not call any of the member functions operator+=, operator+, operator-=, operator-, or operator[ ], which may only be used with random-access iterators.

  • If the range of an iterator is [_First, _Last), where the square bracket on the left indicates the inclusion on _First and the parenthesis on the right indicates the inclusion of elements up to _Left but excluding _Left itself.

  • The same elements are included in the reversed sequence [rev – _First, rev – _Left) so that if _Left is the one-past-the-end element in a sequence, then the first element rev – _First in the reversed sequence points to *(_Left – 1). The identity which relates all reverse iterators to their underlying iterators is:

&*(reverse_iterator (i)) == &*(i – 1)

  • In practice, this means that in the reversed sequence the reverse_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).

The reverse_iterator Template Class Members

 

Typedefs

 

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

 

The reverse_iterator::operator[ ]

reference operator[](difference_type _Off) const;

 

Parameter

 

Parameter

Description

_Off

The offset from the reverse_iterator address.

 

Table 32.26

// 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;

}

 

Output:

 

C++ STL Iterator reverse_iterator, operator[ ]

 

The reverse_iterator::pointer

typedef typename iterator_traits<Iterator>::pointer 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;

}

 

Output:

 

C++ STL Iterator reverse_iterator, pointer

 

Member Functions

 

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

 

The reverse_iterator::base

RandomIterator base() const;

&*(reverse_iterator(i)) == &*(i – 1).

// 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;

}

 

Output:

 

C++ STL Iterator reverse_iterator, base()

 

Operators

 

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 a reverse_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 a reverse_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

  • We can write classes that have the interface of iterators but do something completely different.  The C++ standard library provides several predefined special iterators, iterator adapters.  They extend the functionalities of the iterators.

  • The three iterator adapters are:

  1. Insert iterators

  2. Stream iterators

  3. Reverse iterators

32.2.1  The Insert Iterators

  • Insert iterators, or inserters are used to let algorithms operate in the insert mode rather than in an overwrite mode.

  • In particular, they solve the problem of algorithms that write to a destination that does not have enough storage; they let the destination grow accordingly.

  • The following table lists the insert iterators and their functionality.

 

Insert iterator

Operation

back_inserter(container)

Appends in the same order by using push_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;

}

 

Output:

 

C++ STL Iterator inserter

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 the insert() 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

 

32.2.2  A Stream Iterators

// 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;

}

 

Output:

 

C++ STL Iterator stream iterator

 

32.2.3  A Reverse Iterators

// 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;

}

 

Output:

 

C++ STL Iterator reverse_iterator using rbegin() and rend()

// ******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--------------------------------------

tenouk C++ STL tutorial

 

 

 

 

 

 

 

 

 

 

 

Further C++ STL iterators related reading:

 

  1. C++ Templates programming tutorials.

  2. The source code for this tutorial is available in C++ STL Iterator source code samples.

  3. A complete C & C++ Standard Library documentation that includes STL.

  4. Check the best selling C / C++ and STL books at Amazon.com.

 

 

 

 

 

 

|< C++ STL Iterator 6 | Main | C++ STL Algorithm 1 >| Site Index | Download |


C++ STL Iterators Classes:  Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6 | Part 7