Sunday, November 20, 2011

iterator stl

iterator c++

An iterator is an object that can "iterate" (navigate) over  elements. These elements may be all or part of the elements of a  STL container. An iterator represents a certain position in a  container. The following fundamental operations define the behavior of an iterator:
  • Operator * : Returns the element of the actual position. If the elements have members, you can use operator -> to access those members directly from the iterator. ( In some older environments, operator -> might not work yet for iterators.) 
  • Operator ++ : Lets the iterator step forward to the next element. Most iterators also allow stepping backward by using operator --. 
  • Operators == and != : Return whether two iterators represent the same position. 
  • Operator = Assigns an iterator (the position of the element to which it refers).
These operations are exactly the interface of ordinary pointers  in C and C++ when they are used to iterate over the elements of an array. The difference is that iterators may be smart pointers — pointers that iterate over more complicated data structures of  containers. The internal behavior of iterators depends on the data structure over which they iterate. Hence, each container type supplies its own kind of iterator. In fact, each container  class defines its iterator type as a nested class. As a result, iterators share the same interface but have different types. This leads directly to the concept of generic programming: Operations  use the same interface but different types, so you can use templates to formulate generic operations that work with  arbitrary types that satisfy the interface.

All container classes provide the same basic member functions  that enable them to use iterators to navigate over their  elements. The most important of these functions are as follows:  
  • begin() : Returns an iterator that represents the beginning of the elements in the container. The beginning is the position of the first element (if any). 
  • end() : Returns an iterator that represents the end of the elements in the container. The end is the position behind the last element. Such an iterator is also called a past-the-end iterator.
Thus, begin() and end() define a half-open range that includes  the first element but excludes the last (Figure 5.3). A half-open range has two advantages:

Figure. begin() and end() for Containers
  1. You have a simple end criterion for loops that iterate over the elements: They simply continue as long as end() is not reached. 
  2. It avoids special handling for empty ranges. For empty ranges, begin() is equal to end().
Here is an example demonstrating the use of iterators. It prints  all elements of a list container (it is the promised enhanced  version of the first list example).

Example:

After the list is created and filled with the characters 'a' through 'z', all elements are printed within a for loop:

list<char>::const_iterator pos;
for (pos = coll.begin(); pos != coll.end(); ++pos) {
   cout << *pos << ' ';
}

The iterator pos is declared just before the loop. Its type is the iterator type for constant element access of its container class:

list<char>::const_iterator pos;

Every container defines two iterator types:
  1. container::iterator - is provided to iterate over elements in read/write mode. 
  2. container: : const_iterator - is provided to iterate over elements in read-only mode.
For example, in class list the definitions might look like the following:

namespace std {
   template <class T>
   class list {
      public:
         typedef ... iterator;
         typedef ... const_iterator;
         ...
   };
}

The exact type of iterator and const_iterator is implementation  defined.

Inside the for loop, the iterator pos first gets initialized with  he position of the first element:

pos = coll.begin()

The loop continues as long as pos has not reached the end of the  container elements:

pos != coll.end()

Here, pos is compared with the past-the-end iterator. While the  loop runs the increment operator, ++pos navigates the iterator pos to the next element.

All in all, pos iterates from the first element, element- by-element, until it reaches the end (Figure below). If the  container has no elements, the loop does not run because  coll.begin() would equal coll.end().

Figure . Iterator pos Iterating Over Elements of a List

In the body of the loop, the expression *pos represents the  actual element. In this example, it is written followed by a  space character. You can't modify the elements because a const_iterator is used. Thus, from the iterator's point of view  the elements are constant.

However, if you use a nonconstant iterator and the type of the  elements is nonconstant, you can change the values. For example:  
//make all characters in the list uppercase
list<char>::iterator pos;
for (pos = coll.begin(); pos != coll.end(); ++pos) {
   *pos = toupper(*pos);
}

Note that the preincrement operator (prefix ++) is used here.  This is because it might have better performance than the  postincrement operator. The latter involves a temporary object  because it must return the old position of the iterator. For this  eason, it generally is best to prefer ++pos over pos++. Thus, you should avoid the following version:

for (pos = coll.begin(); pos != coll.end(); pos++) {
   ^^^^^ // OK, but slower
  ...
}

For this reason, I recommend using the preincrement and pre-decrement operators in general.

See Also:

2 comments:

  1. change the background....because continuously not able to see the monitor...if you change the background i am refer this site to many...

    ReplyDelete
  2. Hi,

    I will try that soon. As we need to change and check the preview for other related pages and posts also.

    Thanks for suggestion.

    --Saurabh Gupta
    sgupta@ccplusplus.com

    ReplyDelete