Iterator
在上次我们初步得看完整个range
的concept后,我们不难发现,基本上大部分的range
定义都依赖于对其迭代器的定义,所以这次我们就来看一下iterator/concepts.hpp
中的各种迭代器的concept定义。
但是在直接看concept之前,我们得先看一下iterator/traits.hpp
中的各种traits。
Traits
- 各种
iterator_tag
:input_iterator_tag
forward_iterator_tag : input_iterator_tag
bidirectional_iterator_tag : forward_iterator_tag
random_access_iterator_tag : bidirectional_iterator_tag
contiguous_iterator_tag : random_access_iterator_tag
iter_rvalue_reference_t
: 获取迭代器解引用后的类型的右值形式iter_common_reference_t
: 获取一种迭代器解引用后的类型与迭代器的value_type
的common_type
(两者都能被转化到的一个类型)的引用形式iter_difference_t
: 获取迭代器的difference_type
,即用来表示迭代器距离的类型iter_value_t
: 获取迭代器的value_type
iter_reference_t
: 获取迭代器解引用后的类型的引用形式
Concept
detail::iter_concept_t
: 获取迭代器的类别信息,其具体按照以下顺序排布的过程来获取这一信息:- 如果迭代器是指针,返回
contiguous_iterator_tag
- 如果有
iter_traits_t<I>::iterator_concept
,则返回这个iterator_concept
- 如果有
iter_traits_t<I>::iterator_category
,则返回这个iterator_category
- 如果没有特化
std::iterator_traits<I>
,返回random_access_iterator_tag
- 如果迭代器是指针,返回
indirectly_readable
: 间接可读的,要求迭代器的const
形式的解引用的结果的类型与iter_reference_t<I>
相同;const
形式的迭代器解引用的结果的右值形式与iter_rvalue_reference_t<I>
相同。简单地来说,就是要求迭代器能解引用且其的解引用的结果的类型不会因为迭代器是不是const
的而产生变化indirectly_writable
: 间接可写的,要求迭代器的左值和右值引用形式都可以支持接受类型T
的赋值操作(这里我又在源码里学到一个新知识点:const
同&&
一样都不会对左值引用类型产生影响)detail::integer_like_
: 要求类型是一种数值类型detail::signed_integer_like_
: 要求类型是一种有符号数值类型weakly_incrementable
: 弱可增长的,要求迭代器是一个semiregular
(可默认构造,可拷贝),并且其要支持++i
、i++
这两种操作,其中++i
的返回类型得是I&
,同时这个迭代器类型I
得有difference_type
,且其difference_type
得符合detail::signed_integer_like_
incrementable
: 可增长的,首先要求迭代器是一个regular
(semiregular
加上可做等同性比较),并且其得符合weakly_incrementable
,且要求i++
的返回类型是I
(个人认为const I
在语义上更为严谨,可能是历史遗留问题吧)input_or_output_iterator
: 可以输入或输出的迭代器,要求迭代器可以解引用(支持operator*()
),同时其也得满足weakly_incrementable
sentinel_for
: 接受一个待检验的守卫类型S
和一个迭代器类型I
,其要求守卫类型S
是一个semiregular
,I
是一个input_or_output_iterator
,同时S
和I
是满足弱相等的disable_sized_sentinel<S,I>
: 类似range
中的disable_sized_range
,表示这个守卫类型是不是不能求大小的,其默认值为false
sized_sentinel_for
: 接受一个待检验的守卫类型S
和一个迭代器类型I
,其要求这两者满足sentinel_for<S,I>
,同时disable_sized_sentinel<S,I>
的值要为false
,支持s - i
和i - s
这两种操作,且这两种操作的返回值的类型要与iter_difference_t<I>
(即I::difference_type
)相同output_iterator
: 要求迭代器是input_or_output_iterator
的,同时满足indirectly_writable<Out, T>
,且支持*o++ = (T &&) t
操作input_iterator
: 要求迭代器是input_or_output_iterator
的,同时满足indirectly_readable<Out, T>
,且对其使用detail::iter_concept_t
求得的tag是input_iterator_tag
forward_iterator
: