STL是基于各种concept的。
其中几种基本concept有:
Assignable, default constructible, Equality comparable, LessThan comparable.
Iterator is the connection between algorithm and container, so, it plays a pivotal role
in STL.
>Input Iterator:
1: dereferenceable (*P), past the end, singular (null).
2: equality comparable
3: assignable
4: ++p or p++
5: unchangable.
6: single pass
7: read only *ite = *p wrong, *p = *ite right.
>Output Iterator:
1: dereferenceable (*P), past the end, singular (null).
2: equality comparable
3: assignable
4: ++p or p++
5: changable.
6: single pass
7: write only *ite = *p right, *p = *ite wrong.
>Foreward Iterator
1: dereferenceable (*P), past the end, singular (null).
2: equality comparable
3: assignable
4: ++p or p++
5: changable.
6: mullti-pass
7: write or read *ite = *p right, *p = *ite right.
8: constant iterator and mutable iterator (ref to 7)
>bidirectional iterator
1: dereferenceable (*P), past the end, singular (null).
2: equality comparable
3: assignable
4: ++p or p++
5: changable.
6: mullti-pass
7: write or read *ite = *p right, *p = *ite right.
8: constant iterator and mutable iterator (ref to 7)
9: --p or p--
> random iterator
1: dereferenceable (*P), past the end, singular (null).
2: equality comparable
3: assignable
4: ++p or p++, --p or p--, p+n or p-n, p[n]
5: changable.
6: mullti-pass
7: write or read *ite = *p right, *p = *ite right.
8: constant iterator and mutable iterator (ref to 7)
9: Key difference: 能以固定时间访问任意元素。
************************************************************************************
*******************************华丽的分割线********************************************
************************************************************************************
问题:希望从iterator中能获取其指向的值类型
解决方案:在iterator中定义 value_type
template <typename T>
struct iterator {
typedef T value_type;
......
}
typename iterator::value_type class_name;
class_name obj;
问题:对于非类定义的iterator不适用,比如指针
解决方案:添加中间层iterator_traits
template <typename iterator>
struct iterator_traits {
typedef typename iterator::value_type value_type;
}
然后可以根据实际情况,定义iterator_traits的偏特化实现:
template <>
struct iterator_traits<char *> {
typedef typename char value_type;
};
In fact, the implement is:
template <typename T>
struct iterator_traits<T*> {
typedef T value_type;
};
and following:
template <typename T>
struct iterator_traits<const T*> {
typedef T value_type;
};
Problem: For random iterator,
difference type. Sometimes, we want to know the distance between two iterator
Resolve: As we see in value_type:
template<typename T>
struct iterator_traits {
typedef T::difference_type difference_type;
}
template<typename T>
struct iterator_traits<T*> {
typedef ptrdiff_t difference_type;
}
template<typename T>
struct iterator_traits<const T*> {
typedef ptrdiff_t difference_type;
}
同理,对值类型的指针,引用类型都可以在中间层 iterator_traits中定义。
pointer;
reference;
最终,iterator是和算法一起运作的,在算法的实现过程中,对不同的iterator,其算法
复杂度也有很大不同,因此如何识别一个iterator是何种类型的iterator就成了一个问题。
当然,在C++中可以通过typeof关键字来识别,但那是基于运行期的,速度会很慢。
STL中的结局方案是在iterator中定义一个没有实际作用的类型
iterator {
typedef XXXX iterator_category;
}
template <typename _ite>
struct iterator_traits {
typedef typename _ite::iterator_category iterator_category;
}
The XXX would be following values:
input_iterator_tag
output_iterator_tag
forward_iterator_tag
bidirectional_iterator_tag
random_access_iterator_tag
该技术本质上是一种dispatching
**********************************
**********************************
总而言之,iterator_traits出现的必要性有:
1 需要返回某值,或是声明临时变量,而其类型同iterator的值类型有关。
2 算法需要根据不同的iterator类型决定不同的实现。
**********************************
**********************************
iterator是constant or mutable, the difference is the pointer type
and reference type.
**********************************
**********************************
iterator 相等原则:两个iterator指向同一个对象时,才能定义
两个iterator相等。