![]() |
![]() |
![]() |
|
Categories: iterators, adaptors | Component type: type |
template <class T> void forw(const list<T>& L) { list<T>::iterator first = L.begin(); list<T>::iterator last = L.end(); while (first != last) cout << *first++ << endl; } template <class T> void rev(const list<T>& L) { typedef reverse_bidirectional_iterator<list<T>::iterator, T, list<T>::reference_type, list<T>::difference_type> reverse_iterator; [2] reverse_iterator rfirst(L.end()); reverse_iterator rlast(L.begin()); while (rfirst != rlast) cout << *rfirst++ << endl; }In the function forw, the elements are printed in the order *first, *(first+1), ..., *(last-1). In the function rev, they are printed in the order *(last - 1), *(last-2), ..., *first. [3]
Parameter | Description | Default |
---|---|---|
BidirectionalIterator | The base iterator class. Incrementing an object of class reverse_bidirectional_iterator<BidirectionalIterator> corresponds to decrementing an object of class BidirectionalIterator. | |
T | The reverse iterator's value type. This should always be the same as the base iterator's value type. | |
Reference | The reverse iterator's reference type. This should always be the same as the base iterator's reference type. | T& |
Distance | The reverse iterator's distance type. This should always be the same as the base iterator's distance type. | ptrdiff_t |
Member | Where defined | Description |
---|---|---|
self | reverse_bidirectional_iterator | See below |
reverse_bidirectional_iterator() | Trivial Iterator | The default constructor |
reverse_bidirectional_iterator(const reverse_bidirectional_iterator& x) | Trivial Iterator | The copy constructor |
reverse_bidirectional_iterator& operator=(const reverse_bidirectional_iterator& x) | Trivial Iterator | The assignment operator |
reverse_bidirectional_iterator(BidirectionalIterator x) | reverse_bidirectional_iterator | See below. |
BidirectionalIterator base() | reverse_bidirectional_iterator | See below. |
Reference operator*() const | Trivial Iterator | The dereference operator |
reverse_bidirectional_iterator& operator++() | Forward Iterator | Preincrement |
reverse_bidirectional_iterator operator++(int) | Forward Iterator | Postincrement |
reverse_bidirectional_iterator& operator--() | Bidirectional Iterator | Predecrement |
reverse_bidirectional_iterator operator--(int) | Bidirectional Iterator | Postdecrement |
bool operator==(const reverse_bidirectional_iterator&, const reverse_bidirectional_iterator&) | Trivial Iterator | Compares two iterators for equality. This is a global function, not a member function. |
bidirectional_iterator_tag iterator_category(const reverse_bidirectional_iterator&) | Iterator tags | Returns the iterator's category. This is a global function, not a member function. |
T* value_type(const reverse_bidirectional_iterator&) | Iterator tags | Returns the iterator's value type. This is a global function, not a member function. |
Distance* distance_type(const reverse_bidirectional_iterator&) | Iterator tags | Returns the iterator's distance type. This is a global function, not a member function. |
Member | Description |
---|---|
self | A typedef for reverse_bidirectional_iterator<BidirectionalIterator, T, Reference, Distance>. |
BidirectionalIterator base() | Returns the current value of the reverse_bidirectional_iterator's base iterator. If ri is a reverse iterator and i is any iterator, the two fundamental identities of reverse iterators can be written as reverse_bidirectional_iterator(i).base() == i and &*ri == &*(ri.base() - 1). |
reverse_bidirectional_iterator(BidirectionalIterator i) | Constructs a reverse_bidirectional_iterator whose base iterator is i. |
[1] There isn't really any good reason to have two separate classes: this separation is purely because of a technical limitation in today's C++ compilers. If the two classes were combined into one, then there would be no way to declare the return types of the iterator tag functions iterator_category, distance_type and value_type correctly. A mechanism known as iterator traits solves this problem: it addresses the same issues as the iterator tag functions, but more elegantly and flexibly. Iterator traits, however, rely on partial specialization, which is not yet (as of September 1996) supported by any shipping compiler. Once compilers that support partial specialization become available, future releases of the STL will use iterator traits and will combine the two different reverse iterator classes into one.
[2] The declarations for rfirst and rlast are written in this clumsy form simply as an illustration of how to declare a reverse_bidirectional_iterator. List is a Reversible Container, so it provides a typedef for the appropriate instantiation of reverse_bidirectional_iterator. The usual way of declaring these variables is much simpler:
list<T>::reverse_bidirectional_iterator rfirst = rbegin(); list<T>::reverse_bidirectional_iterator rlast = rend();
[3] Note the implications of this remark. The variable rfirst is initialized as reverse_bidirectional_iterator<...> rfirst(V.end());. The value obtained when it is dereferenced, however, is *(V.end() - 1). This is a general property: the fundamental identity of reverse iterators is &*(reverse_bidirectional_iterator(i)) == &*(i - 1). This code sample shows why this identity is important: if [f, l) is a valid range, then it allows [reverse_bidirectional_iterator(l), reverse_bidirectional_iterator(f)) to be a valid range as well. Note that the iterator l is not part of the range, but it is required to be dereferenceable or past-the-end. There is no requirement that any such iterator precedes f.