STL源码剖析:迭代器

准备知识

什么是迭代器?
  • 迭代器是链接容器和算法的桥梁,所有的算法都通过迭代器操作容器中的数据

  • 迭代器是一种智能指针,最重要的操作符重载就是operator*,operator->

  • 迭代器的实现需要知道容器的具体细节,因此每一种容器都对应自己特有的迭代器,但是迭代器的接口是一致的

Traits编程技巧
  • 目的:提取出容器中存放的数据类型

  • 核心是使用模板技术,在编译期就确认需要调用的函数

  • 嵌套从属名称:

template <typename T>
class Data
{
    typedef T value_type;
};

template <typename T>
class Type
{
    // typename T::value_type 就是一个嵌套从属名称,其中的typename不能掉
    // 理解模板类型中使用模板类型
    typedef typename T::value_type value_type;  
};

int main()
{
    Type<Data<int>>::value_type a(); // a()表示一个类型为int的变量
}
占位参数实现函数重载
  • 占位参数是函数参数,只是这种参数只有参数类型,没有参数名

  • 占位参数同样属于参数列表,可以实现重载

// int是占位参数
void print(int)
{
    cout << "void print(int)" << endl;
}

void print()
{
    cout << "void print()" << endl;
}

int main()
{
    print(1); // 调用void print(int)
    print(); // 调用void print()
}

源码

常用的迭代器相应类型
  • 一般在迭代器中常用的容器类型一共5种

template <class I>
struct iterator_traits 
{
    typedef typename I::iterator_category iterator_category;
    typedef typename I::value_type value_type;
    typedef typename I::difference_type difference_type;
    typedef typename I::pointer pointer;
    typedef typename I::reference reference
};

/*
value_type:迭代器所指数据类型
difference_type:表示两个迭代器之间距离的类型
reference:数据内容本身类型
pointer:与reference对应的指针类型
iterator_category:
    Input Iterator:只读
    Output Iterator:只写
    Forward Iterator:可读可写,只能前进,每次前进一个单位
    Bidirectional Iterator:可读可写,双向移动,每次移动一个单位
    Random Access Iterator:可读可写,双向移动,每次移动多个单位
*/
  • 由于原生的指针类型并没有提供者5种类型的定义,因此进行特化处理
// 实现原生指针的类型提取
template <class T>
struct iterator_traits<T*> 
{
    ...
    typedef T* pointer;
    typedef T& reference;
};

// 实现const指针的类型提取,去掉const属性,因为会通过迭代器操作容器中的数据
template <class T>
struct iterator_traits<const T*> 
{
    ...
    typedef const T* pointer;
    typedef const T& reference;
};
  • 5种iterator_category的类型定义,都只是类型定义,没有任何成员
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完整代码
  • 迭代器类型相关代码

// 五种迭代器类型
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 {};

// 定义一个基础类,提供迭代器需要的类型定义,编译继承实现,防止遗漏
template <class Category, class T, class Distance = ptrdiff_t, class Pointer = T*, class Reference = T&>
struct iterator
{
    typedef Category     iterator_category;
    typedef T            value_type;
    typedef Distance    difference_type;
    typedef Pointer        pointer;
    typedef Reference    reference;
};

// 类型提取
template <class Iterator>
struct iterator_traits {
    typedef typename Iterator::iterator_category iterator_category;
    typedef typename Iterator::value_type
    typedef typename Iterator::difference_type
    typedef typename Iterator::pointer
    typedef typename Iterator::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;
};

// 针对const指针的特化处理
template <class T>
struct iterator_traits<const T*> {
    typedef random_access_iterator_tag            iterator_category;
    typedef T                                    value_type;
    typedef ptrdiff_t                            difference_type;
    typedef const T*                            pointer;
    typedef const T&                            reference;
};

// 该函数非常方便的提取某个迭代器的类型iterator_category
template <class Iterator>
inline typename iterator_traits<Iterator>::iterator_category iterator_category(const Iterator&) 
{
    typedef typename iterator_traits<Iterator>::iterator_category category;
    return category();
}

// 该函数非常方便的提取某个迭代器的类型difference_type
template <class Iterator>
inline typename iterator_traits<Iterator>::difference_type* distance_type(const Iterator&) 
{
    return static_cast<typename iterator_traits<Iterator>::difference_type*>(0);
}

// 该函数非常方便的提取某个迭代器的类型value_type
template <class Iterator>
inline typename iterator_traits<Iterator>::value_type* value_type(const Iterator&)
{
    return static_cast<typename iterator_traits<Iterator>::value_type*>(0);
}
  • advance函数
// 迭代器前进
template <class InputIterator, class Distance>
inline void advance(InputIterator& i, Distance n) 
{
    __advance(i, n, iterator_category(i));
}

// radom迭代器前进
template <class RandomAccessIterator, class Distance>
inline void __advance(RandomAccessIterator& i, Distance n, random_access_iterator_tag)
{
    i += n;
}

// bidirectional迭代器前进
template <class BidirectionalIterator, class Distance>
inline void __advance(BidirectionalIterator& i, Distance n, bidirectional_iterator_tag) 
{
    if (n >= 0)
        while (n--) ++i;
    else
        while (n++) --i;
}

// input迭代器前进
template <class InputIterator, class Distance>
inline void __advance(InputIterator& i, Distance n, input_iterator_tag) 
{
    while (n--) ++i;
}
  • distance函数
// 计算迭代器之间的距离
template <class InputIterator>
inline iterator_traits<InputIterator>::difference_type distance(InputIterator first, InputIterator last) 
{
    typedef typename iterator_traits<InputIterator>::iterator_category category;
    return __distance(first, last, category());
}

// 计算random迭代器之间的距离
template <class RandomAccessIterator>
inline iterator_traits<RandomAccessIterator>::difference_type __distance(RandomAccessIterator first, RandomAccessIterator last,
random_access_iterator_tag) 
{
    return last - first;
}

// 计算Input迭代器的距离
template <class InputIterator>
inline iterator_traits<InputIterator>::difference_type __distance(InputIterator first, InputIterator last, input_iterator_tag)
{
    iterator_traits<InputIterator>::difference_type n = 0;
    while (first != last) 
    {
        ++first; 
        ++n;
    }
    return n;
}
  • __type_traits技术
    • 不属于标准的STL,属于SGI STL的私有代码

    • 技术和iterator_traits技术相同,只是定义的类型不同,作用场合不同

    • 如POD就是__type_traits中定义的一种类型

    • 部分代码如下:

struct __true_type { };
struct __false_type { };

template <class type>
struct __type_traits
{
    typedef __true_type this_dummy_member_must_be_first;
    typedef __false_type has_trivial_default_constructor;
    typedef __false_type has_trivial_copy_constructor;
    typedef __false_type has_trivial_assignment_operator;
    typedef __false_type has_trivial_destructor;
    typedef __false_type is_POD_type; // 是否是POD类型
};

__STL_TEMPLATE_NULL struct __type_traits<char> {
    typedef __true_type has_trivial_default_constructor;
    typedef __true_type has_trivial_copy_constructor;
    typedef __true_type has_trivial_assignment_operator;
    typedef __true_type has_trivial_destructor;
    typedef __true_type is_POD_type;
};
__STL_TEMPLATE_NULL struct __type_traits<signed char> 
{
    typedef __true_type has_trivial_default_constructor;
    typedef __true_type has_trivial_copy_constructor;
    typedef __true_type has_trivial_assignment_operator;
    typedef __true_type has_trivial_destructor;
    typedef __true_type is_POD_type;
};
__STL_TEMPLATE_NULL struct __type_traits<unsigned char> 
{
    typedef __true_type has_trivial_default_constructor;
    typedef __true_type has_trivial_copy_constructor;
    typedef __true_type has_trivial_assignment_operator;
    typedef __true_type has_trivial_destructor;
    typedef __true_type is_POD_type;
};
__STL_TEMPLATE_NULL struct __type_traits<short> 
{
    typedef __true_type has_trivial_default_constructor;
    typedef __true_type has_trivial_copy_constructor;
    typedef __true_type has_trivial_assignment_operator;
    typedef __true_type has_trivial_destructor;
    typedef __true_type is_POD_type;
};

// ... 每种基本类型都有定义

// 对原生的指针类型进行定义
template <class T>
struct __type_traits<T*> 
{
    typedef __true_type has_trivial_default_constructor;
    typedef __true_type has_trivial_copy_constructor;
    typedef __true_type has_trivial_assignment_operator;
    typedef __true_type has_trivial_destructor;
    typedef __true_type is_POD_type;
};

猜你喜欢

转载自www.cnblogs.com/chusiyong/p/11574026.html