概述
五种迭代器类型
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 { };
这里的 xxx_iterator_tag 类型是用来对函数重载起作用的
运用继承的原因在后续代码实例中解释。
为避免写代码时挂一漏万,自行开发的迭代器最好继承下面这个 std::iterator
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;
};
榨汁机 traits
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;
};
针对原生指针而设计的 traits 偏特化版
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;
};
针对原生之 pointer-to-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;
};
三个全局函数
这个函数可以很方便地决定某个迭代器的类型 (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();
}
这个函数可以很方便地决定某个迭代器的 distance 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);
}
以下是整组 distance (一个实例)
作用是求两个迭代器之间的距离。显然,该函数针对迭代器是否有 + n 这个运算分开来写的。 在 lower_bound 等算法中有使用到。
即两种,RandomAccessIterator 和 非 RandomAccessIterator。 而运用继承机制,当我们调用这个函数传入的 BidirectionalIterator 时,它会自动转为 InputIterator,从而有一个合法的函数匹配。其他的,如 ForwardIterator 也是同理。
同时,也可以发现,xxx_iterator_tag 的作用只是帮助形成函数重载。
template <class 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;
}
return n;
}
template <class RandomAccessIterator>
inline typename iterator_traits<RandomAccessIterator>::difference_type
__distance(RandomAccessIterator first, RandomAccessIterator last,
random_access_iterator_tag) {
return last - first;
}
template <class InputIterator>
inline typename iterator_traits<InputIterator>::difference_type
distance(InputIterator first, InputIterator last) {
typedef typename iterator_traits<InputIterator>::iterator_category category;
return __distance(first, last, category());
}
以下是整组 advance 函数
该函数的作用是,取得与迭代器 i 距离为 n 处的迭代器。 在 lower_bound 等算法中有使用到。
与 distance() 类似。这里分为了三种,迭代器只有 ++ 操作;迭代器可 ++,可 --,但是不能 + n;迭代器有 ++,–, +n,+=,-= 等运算。
由于继承的关系,当传入 ForwardIterator,在调用时都会自动转换为 InputIterator,即无需再针对 ForwardIterator 编写一个 __advance()
template <class InputIterator, class Distance>
inline void __advance(InputIterator &i, Distance n, input_iterator_tag) {
while(n --) ++ i;
}
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;
}
template <class RandomAccessIterator,class Distance>
inline void __advance(RandomAccessIterator &i, Distance n,
random_access_iterator_tag) {
i += n;
}
template <class InputIterator, class Distance>
inline void advance(InputIterator &i, Distance n) {
__advance(i, n, iterator_category(i));
}
__type_traits
__type_traits 与 iterator_traits 很类似,用来萃取其类型是否含有:trivial_default_constructor,trivial_copy_constructor,是否是 POD 类型等。
同样的,为了便于重载,还提供了两个类:
struct __true_type{};
struct __false_type{};
__type_traits 默认将以上类型都设置为 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_constructor;
typedef __false_type has_trivial_destructor;
typedef __false_type is_POD_type;
};
并针对所有的内置类型编写了特例化的版本:
__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_constructor;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
__STL_TEMPLATE_NULL struct __type_traits<int> {
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_constructor;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
// ... 还有 unsigned char, long, short, unsigned short 等许多内置类型
其应用体现在很多地方,见:https://blog.csdn.net/no_O_ac/article/details/105469821 中的 destroy 源码与 uninitialized_copy 源码
最后
以上就是爱听歌翅膀为你收集整理的STL 源码剖析重要部分:迭代器与Traits编程技法的全部内容,希望文章能够帮你解决STL 源码剖析重要部分:迭代器与Traits编程技法所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复