An example is an iterator reading the file names found in a directory: Initialized with a directory name, the iterator retrieves the names of files storedd in a directory using some system dependent functions (here the POSIX system interface; however, I'm convinced that this also extends to other systems). It makes the current file name accessible using operator*() and reads the next name with operator++(). I have made available the declaration and the implementation of such an implementation including a simple test program and documentation per ftp at ftp://ftp.informatik.uni-konstanz.de/pub/algo/personal/kuehl/dir_it.tgz.
This implementation uses a reference counted representation class storing the information used by the system functions: If a dir_it is copied, only a pointer to this representation is copied and the reference count is increased. This is necessary to allow both copying of iterator and to maintain only one copy of the system information. The current implementation only provides access to the names of the files in the directory. With corresponding adaptors, it would be possible to also create iterator which retrieve several different aspects of the file, e.g. also the size.
The only generally interesting part of such iterators is the definition of the start and the end of the sequence: For directories it makes in general no sense to define subsequences because the system is free to return the directory entries in any order it wishes. Thus, it is not attempted to provide for a definition of a subsequence. With this in mind, it is clear how to construct the iterator marking beginning of a directory: A dir_it is constructed from the directory name. How is the end marker constructed? To avoid unnecessary argument, it should be constructed with the default constructor if possible. However, this is sufficient if the following convention is used: An invalid iterator uses either a null pointer or an invalid representation object as representation. The latter version of the representation is necessary, because several iterators can get invalid at the same time because they may share the same record for the representation. Then, the necessary check for equality, i.e. operator==() and operator!=(), can be implemented by figuring out whether both iterator are valid.