STL Iterators

这篇随笔是The C++ Programming Language Fourth Edition, by Bjarne Stroustrup 第33章STL Iterators的摘录。

1   Introduction

This chapter presents the STL interators and utilities, notably standard-library function objects. The STL consists of the iterator, container, algorithm, and function object parts of the standard library.

 

Iterators are the glue that ties stard-library algorithms to the data. Conversely you can say that iterators are the mechanism  used to mimize an algorithm's dependence on the data structures on which it operates

 

1.1  Iterator Model

An iterator is akin to a pointer in that it provides operations for indirect access (e.g., * for dereferencing) and for moving to point to a new element (e.g., ++ for moving to the next element)

 

1.2   Iterator Categries 

The standard library provides five kind of iterators (five interator categories):

#input iterator: We can iterate forward using ++ and reach each element (repeatedly) using *. We can compare

input iterators using == and !=. this is the kind of iterators that istream offers;

#Output iterator: We can forward using ++ and write once only using *. This is the kind of iterator that ostream offers;

#Forward iterator: We can interate forward using ++ and read and write (unless the elements are const) elements repeatedly using *. If a forward iterator points to a class object, we can use -> to refer to a member. We can compare forward iterators using == and !=. This is the kind of iterators forward_list offers.

#Bidirectional iterator: We can iterate forward using ++ and backward using -- and read and write (unless the elements are const) elements repeatedly using *. if a bidirectional iterator point to a class object we can use -> to refer to a member. We can compare bidrectional iterators using == and !=. This is the kind of iterators that list, map and set offer.

#Random access iterator: We can iterate forward using ++ or += and iterate backward using -- or -= and read write (unless elements are const) elements repeatedly using * or []. If a random-access iterator points to a class object, we can use -> to refer to a member. We can subscript an iterator using [], add an integer using +, and subtract an iteger using -. We can find the distance between two random-access iterators to the same sequence by substracting one from the other. We can compare random-access iterators using ==, !=, <, <=, >, and >=. This is the kind of iterator that vector offers.

 

If you want to do something advanced with iterator categories, use iterator_traits (directly or indrectly).

 

1.3  Iterator Traits

In <iterator>, the standard library provides a set of type functions that allow us to write code specialized for specific properties of an iterator.

 

The iterator tags are types used to select among algorithms based on the type of an iterator. For example, a random-access iterator can go directly to an element:

template<typename iter>
void advance_helper(iter p, int n, random_access_iterator_tag){
    p+=n;
}

On the other hand, a forward iterator must get to the nth element by moving one step at a time (e.g., following links on a list):

 

template<typename iter>
void advance_helper(iter p, int n, forward_iterator_tag){
    if(0<n)
        while(n--0) ++p;
    else if(n<0)
        while(n++) --p;
}

Given these helpers, advance() can consistently use the optimal algorithm:

template<typename iter>
void advance(iter p, int n){    //use the optimal algorithm
    advance_helper(p, n, typename iterator_traits<iter>::iterator_category{});
}

 

posted @ 2015-09-23 00:14  Pat  阅读(225)  评论(0编辑  收藏  举报