What advantages have STL iterators? Why programmers created that notion?
This looks like a homework question, however...
STL is C++. Iterators make it easy to traverse lists of things (usually providing some STL magic juju to handle the types of thing).
Iterators allow you to traverse container members using pointer-like semantics which would otherwise be impractical for containers with non-contiguous storage.
Iterators allow you to separate algorithms from the container. As long as you have a start and end iterator, and know the capabilities of the iterator (random access etc) you can do operations on the range specified by the iterators. For example, see std::for_each
, std::transform
. This way you can implement just one version of an algorithm rather than needing to write a new one for each container on which you wish it to operate.
Iterators make your life easier because you don't need to worry about the underlying structure of the containers you are using in order to iterate over them. This allows you to spend more time working on the algorithms involved than specifics of implementation (which can be complex).
Iterators are in essence improved version of pointers from C. And BTW the two can be mixed since iterators' behavior is similar to that of pointer.
In C++ that would work without problems:
char buf1[3] = { 1, 2, 3 };
std::vector<char> buf2;
buf2.resize(sizeof(buf1));
std::copy( buf1, buf1+sizeof(buf1), buf2.begin() );
std::copy( buf2.begin(), buf2.end(), buf1 );
Iterators provide abstraction. It is not important how you traverse along some container for a method that only wants to operate on the contents of it. Of course iterators need to be more versatile then just that. You want to use the fastest operations avaible but still want to write generic code or you would like iterators that support output. This where type traits come in. This (in combiantion with concepts) is used extensively in the STL
. See the SGI Documentation for an overview.
On the other hand: iterators aren't the best solution for all kinds of problems and thus often get generalized to ranges. (See boost range for an example or this great talk from boostcon.
What advantages have STL iterators?
- They allow you to abstract how you iterate values from what you do with the iterated values allowing for generic algorithms to be written.
Example:
std::vector<int> cont;
auto position = std::find(cont.begin(), cont.end(), 1); // forward search
auto position = std::find(cont.rbegin(), cont.rend(), 1); // backward search
They allow for implementing safe dereferencing (an iterator may be set to throw an exception if it doesn't point to a valid value and you dereference it ), or any other safety checks.
They allow for arbitrary streams to be treated as iterable sequences.
This allows you to iterate I/O streams for example, writing code like this:
std::vector<int> cont;
copy( cont.begin(), cont.end(), std::ostream_iterator<int>(std::cout, " ") );
It looks so much more grown-up to write
vector<myclass>::iterator myClassVectorIterator;
for(myClassVectorIterator = myClassVector.begin();
myClassVectorIterator != myClassVector.end();
myClassVectorIterator++)
rather than
for (int i=0;i<size;i++) { ...
Advantages over what? Is there some alternative you wish to compare iterators to?
C-style integer sequences, such as for(i=0;i!=N;++i)
assume the cost of random access in the container, specifically, the cost of accessing element [i]
, is negligible.
Similarly, pointer increment such as for(p=&arr[0]; p != p+N; ++p
assumes the implementation of the sequence is a contiguous chunk of memory.
Higher level alternatives have been proposed and many implemented. Ranges, Perl-style "foreach" syntax, Lisp-style "apply".
The main reason for iterators in STL was to allow algorithms to be written independent of the manner in which the data was stored. Of course, the storage does (or at least can) impose some limitations, which lead to various classes of iterators (e.g., RandomAccess vs. Input) but these are (intended to be) as independent as possible of the underlying data structure.
This allows, for example, a merge
algorithm to take input from a vector
and a list
, and write the output to an ostream_iterator
, without needing to pay any attention to the differences between the sources and/or destination.