作者: my_passion | 来源:发表于2022-09-25 23:54 被阅读0次

<iterator>

1 种类标签 Category tags

    input/output/forward/bidirectional/random_access  _iterator_tag         
        
    —————————————————————————————————————————————————————————————————————————————————————————————————————————————   
                                        input       `只可解引用为 rvalue`                     *a  / a->m
                                        —————————————————————————————————————————————————————————————————————————       
                                        output      mutable iterator 可解引用为 lvalue       *iter++ = t
                            forward     —————————————————————————————————————————————————————————————————————————       
                                                    `默认构造`                              X iter
            bidirectional   —————————————————————————————————————————————————————————————————————————————————————
                                                    --
            —————————————————————————————————————————————————————————————————————————————————————————————————————
    random_access                                   iter1 + n   / iter1 - n / iter1 - iter2 / iter +=/-= n 

                                                    比较 < > <= >=
                                                    
                                                    `下标` iter[n]
    —————————————————————————————————————————————————————————————————————————————————————————————————————————————   

2 函数

(1) 迭代器操作 

    [1] `std::distance(inputIter1, inputIter2)`
    
    `从 inputIter1 到 inputIter2 要正向走的步数: 正/负 n`
    
        template<class InputIterator>  
            typename iterator_traits<InputIterator>::difference_type    
        distance (InputIterator first, InputIterator last);
        
        可 正/负整数 
    
    
    [2] `std::advance(inputIter, n)`
    
    `将 iter 前移 n(可 < 0) 个 elemPos`  
        if iter 随机 
            operator+/-(n)
        else
            n 次 operator++/--
            
        template <class InputIterator, class Distance>  
            void 
        advance (InputIterator& it, Distance n);
        
    [3] begin()
        |
        end()
    
(2) 迭代器生成器  

    [1] `back_inserter(container)`
        |
        front_inserter(container)
        
        返回 `后插迭代器`, 可 `在容器后插新元素`
        
        template <class Container>  
            back_insert_iterator<Container> 
        back_inserter (Container& c);
        
        // eg
        std::vector<int> foo, bar;
        for (int i=1; i<=5; i++)
        { 
            foo.push_back(i); 
            bar.push_back(i*10); 
        }
        std::copy (bar.begin(), bar.end(), back_inserter(foo) ); // => foo: 1 2 3 4 5 10 20 30 40 50
        
    [2] `inserter(container, containerIter)`
    
        template <class Container>  
            insert_iterator<Container> 
        inserter (Container& x, typename Container::iterator it);
    
        #include <iostream>     
        #include <iterator>     // std::inserter, std::advance 
        #include <list>         // std::list
        #include <algorithm>    // std::copy

        int main () 
        {
            std::list<int> foo, bar;
            for (int i=1; i<=5; i++)
            { 
                foo.push_back(i); 
                bar.push_back(i*10); 
            }

            std::list<int>::iterator it = foo.begin();
            advance (it,3);

            std::copy (bar.begin(),bar.end(),std::inserter(foo,it) ); // 1 2 3 10 20 30 40 50 4 5
        }     

3 类

(1) iterator<IterCategory, T>: 5 种关联型别
给 iterator_traits用于萃取出想要萃取的型别给client

    template <class Category,    // `迭代器种类`
             class T,            // 所指 `元素类型`
             class Distance = ptrdiff_t, // <cstddef> `两指针相减` 的有符号(可 `正/负` ) 整数类型
             class Pointer = T*, 
             class Reference = T&>
    struct iterator 
    {
        typedef T         value_type;
        typedef Distance  difference_type;
        typedef Pointer   pointer;
        typedef Reference reference;
        typedef Category  iterator_category;
    };
        
    `自定义迭代器: 要继承自 std::iterator`
    
        #include <iterator>     

        class MyIterator : public std::iterator<std::input_iterator_tag, int>
        {
        private:
          int* p;
        public:
          MyIterator(int* x) :p(x) {}
          MyIterator(const MyIterator& mit) : p(mit.p) {}
          
          MyIterator& operator++() {++p;return *this;}
          MyIterator operator++(int) {MyIterator tmp(*this); operator++(); return tmp;}
          
          bool operator==(const MyIterator& rhs) const {return p==rhs.p;}
          bool operator!=(const MyIterator& rhs) const {return p!=rhs.p;}
          
          int& operator*() {return *p;}
        };

(2) `iterator_traits<Iterator>`

    template <class Iterator> 
    class iterator_traits;
    
    template <class T> 
    class iterator_traits<T*>;
    
    template <class T> 
    class iterator_traits<const T*>;
    
    template <class Iterator>
    struct iterator_traits 
    {
        typedef typename Iterator::iterator_category    iterator_category;
        typedef typename Iterator::value_type           value_type;
        typedef typename Iterator::difference_type      difference_type;
        typedef typename Iterator::pointer              pointer;
        typedef typename Iterator::reference            reference;
    };
    
    template <class T>
    struct iterator_traits<T*>
    {
        typedef random_access_iterator_tag  iterator_category;
        typedef T                           value_type;
        typedef ptrdiff_t                   difference_type;
        typedef T*                          pointer;
        typedef T&                          reference;
    };

4 取迭代器3种关联型别 的函数模板: 旧STL 自带, 新 STL 可据旧STL 自定义

    // iteratorHelperFunc.h
    #pragma

    #include <iterator>

    template <class Iterator>
    inline typename std::iterator_traits<Iterator>::iterator_category
    iteratorCategory(const Iterator&)
    {
        typename std::iterator_traits<Iterator>::iterator_category iterCategory;
        return iterCategory();
    }

    template <class Iterator>
    inline typename std::iterator_traits<Iterator>::value_type*
    valuePtrType(const Iterator&)
    {
        return static_cast<typename std::iterator_traits<Iterator>::value_type*>(0);
    }

    template <class Iterator>
    inline typename std::iterator_traits<Iterator>::difference_type*
    differencePtrType(const Iterator&)
    {
        return static_cast<typename std::iterator_traits<Iterator>::difference_type*>(0);
    }
    
    // test.cpp
    #include "iteratorHelperFunc.h"

    #include <list>
    #include <iostream>

    template<class BidirectionalIter, class ValueType>
    void f1(BidirectionalIter first, BidirectionalIter last, ValueType*)
    {
        ValueType value = *first;
        std::cout << value << std::endl; // 5
    }

    template<class BidirectionalIter, class DifferenceType>
    void f2(BidirectionalIter first, BidirectionalIter last, DifferenceType*)
    {
        DifferenceType d = std::distance(first, last);
        std::cout << d << std::endl;    // 1
    }

    int main()
    {
        std::list<int> lst;
        lst.push_back(5);
        using Iter = std::list<int>::iterator;
        Iter first = lst.begin();
        Iter last = lst.end();

        f1(first, last, valuePtrType(first) );
        f2(first, last, differencePtrType(first) );
    }

Note const_iterator 类型

对容器内元素 `只读`

`解引用` 得 `const (对象的) 引用`

5 输出/入流迭代器

ostream_iterator 需要知道所要打印的对象类型

    template <class T,          // T: 所要输出的对象类型
              class charT=char, 
              class traits=char_traits<charT> > 
    class ostream_iterator;
    
    // Ctor: 第2参数为分隔符
    ostream_iterator (ostream_type& s 
                      [,const char_type* delimiter]); 
    transform(stringPtrSet.begin(), stringPtrSet.end(),
              ostream_iterator<string>(std::cout, "\n"), // 输出区间迭代器
              Dereference() );
    template<class T,        // T: 所要输入的对象类型
             ...>
    class istream_iterator; 
    
    // Ctor: 
    istream_iterator();                 // 默认 Ctor: end-of-stream iterator
    istream_iterator (istream_type& s); // 输入流 iterator
    int main()
    {
        std::istream_iterator<double> eos;              // end-of-stream iterator
        std::istream_iterator<double> iit (std::cin);   // stdin iterator

        if (iit != eos) 
            value1=*iit;
        ++iit;
        if (iit != eos) 
            value2=*iit;

        std::cout << (value1*value2) << '\n';
    }

相关文章

网友评论

    本文标题:

    本文链接:https://www.haomeiwen.com/subject/doezortx.html