STL之iterator源碼解析

摘要

迭代器是一種行爲相似指針的對象,本文介紹iterator與traits的關係,以及對traits內容的補充。包含stl_iterator.h的部份內容,並用c++11對其進行略微改寫。c++

iterator的五種類型

上篇文章已經介紹了這五種類型的特徵,它們只是爲了激活重載機制而設定,並不須要其餘成員。它們的定義以下:dom

//五種迭代器類型
struct input_iterator_tag{};
struct output_iterator_tag{};
struct forward_iterator_tag: public input_iterator_tag { };
struct bidirectional_iterator_tag: public forward_iterator_tag{ };
struct random_access_iterator_tag: public bidirectional_iterator_tag{ };

接下來是iterator的定義:函數

//自造的iterator最好繼承下面的std::iterator
template<typename Category, typename T, 
         typename Distance = ptrdiff_t, 
         typename Pointer = T*,
         typename Reference = T&>
struct iterator
{
    using iterator_category = Category;
    using value_type = T;
    using difference_type = Distance;
    using pointer = Pointer;
    using reference = Reference;
};

//萃取機Traits
//萃取出迭代器的特性
template<typename Iterator>
struct iterator_traits
{
    using iterator_category = typename Iterator::iterator_category;
    using value_type = typename Iterator::value_type;
    using difference_type = typename Iterator::difference_type;
    using pointer = typename Iterator::pointer;
    using reference = typename Iterator::reference;
};
//針對原生指針的片特化版本
template<typename T>
struct iterator_traits<T*>
{
    using iterator_category = random_access_iterator_tag;
    using value_type = T;
    using difference_type = ptrdiff_t;
    using pointer = T*;
    using reference = T&;
};
//pointer-to-const
template<typename T>
struct iterator_traits<const T*>
{
    using iterator_category = random_access_iterator_tag;
    using value_type = T;
    using difference_type = ptrdiff_t;
    using pointer = const T*;
    using reference = const T&;
};
//肯定某個迭代器類型,並返回該類型的一個迭代器對象,方便進行函數重載
template<typename Iterator>
inline typename iterator_traits<Iterator>::iterator_category
iterator_category(const Iterator&)
{
    using category = typename iterator_traits<Iterator>::iterator_category;
    return category();
}
//肯定某個迭代器的distance type
template<typename Iterator>
inline typename iterator_traits<Iterator>::difference_type*
distance_type(const Iterator&)
{
    return static_cast<typename iterator_traits<Iterator>::difference_type*>(nullptr);
}
//肯定某個迭代器的value type
template<typename Iterator>
inline typename iterator_traits<Iterator>::value_type*
value_type(const Iterator&)
{
    return static_cast<typename iterator_traits<Iterator>::value_type*>(nullptr);
}

//整個distance函數的實現,第三個參數只是激活重載機制,無其餘用處
template<typename InputIterator>
inline typename iterator_traits<InputIterator>::difference_type
_distance(InputIterator first, InputIterator last, input_iterator_tag)
{
    typename iterator_traits<InputIterator>::difference_type n = 0;
    while(first != last)
    {
        ++first;
        ++n;
    }
}

template<typename RandomAccessIterator>
inline typename iterator_traits<RandomAccessIterator>::difference_type
_distance(RandomAccessIterator first, RandomAccessIterator last, random_access_iterator_tag)
{
    return last - first;
}
//對外接口,適應不一樣類型的迭代器
template<typename InputIterator>
inline typename iterator_traits<InputIterator>::difference_type
distance(InputIterator first, InputIterator last)
{
    //先利用traits肯定迭代器的類型
    using category = typename iterator_traits<InputIterator>::iterator_category;
    //利用函數重載,第三個參數只是激活重載機制,無其餘用處
    _distance(first, last, category());
}

//整個advance函數的實現,第三個參數只是激活重載機制,無其餘用處
template<typename InputerIterator, typename Distance>
inline void _advance(InputerIterator& i, Distance n, input_iterator_tag)
{
    while(n--) ++i;
}

template<typename BidirectionalIterator, typename Distance>
inline void _advance(BidirectionalIterator i, Distance n, bidirectional_iterator_tag)
{
    if(n >= 0)
        while(n--) ++i;
    else
        while(n++) --i;
}

template<typename RandomAccessIterator, typename Distacne>
inline void _advance(RandomAccessIterator& i, Distacne n, random_access_iterator_tag)
{
    i += n;
}

//對外接口,適應不一樣類型的迭代器
template<typename InputIterator, typename Distance>
inline void advance(InputIterator& i , Distance n)
{
    _advance(i, n, iterator_category(i));
}

#endif //STL_ITERATOR_H
相關文章
相關標籤/搜索