ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、视频、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# 第3章 迭代器概念与traits编程技法 迭代器(iterator):提供一种方法,使之能够依序巡访某个聚合物(容器)所含的各个元素,而又无需暴露该聚合物的内部表达方式。 ## 3.1 迭代器设计思维 STL 的中心思想在于:将数据容器(containers)和算法(algorithm)分开,彼此独立设计,最后再以胶着剂将它们撮合在一起。 ## 3.2 迭代器(iterator)是一种smartpointer 迭代器是一种行为类似指针的对象,而指针的各种行为中最常见也是最重要的便是内容提领(dereference)和成员访问(member acess),因此,迭代器最重要的编程工作就是对 `operator*` 和 `operator->` 进行重载(overloading)工作。 ## 3.3 迭代器相应型别(associated types) 在算法中运用迭代器时,很可能会用到其相应型别(associated types),解决办法就是利用 function template 的参数推导(argument deducation)机制。 ```c++ template <class I, class T> void func_impl(I iter, T t) { T temp; // 这里解决了问题,T就是迭代器所指之物的型别。 } template <class I> inline func(I iter) { func_impl(iter, *iter); } ``` ## 3.4 Traits 编程技法 使用参数推导无法解决函数的传回值为 `value type` 的情况,此时需要使用声明内嵌型别: ```c++ template <class T> struct MyIter { typedef T value_type; // 内嵌型别声明(nested type); }; template <class I> typename I::value_type func I::value_type func(I ite) { return *ite; } ``` 关键词 `typename` 的用意在于告诉编译器这是一个型别。 声明内嵌类型方法有个隐晦的陷阱:并不是所有迭代器都是 class type,例如原生指针,如果不是 class type,就无法为它定义内嵌型别。 此时可以用 class template 提供的萃取,并通过模版便特化处理指针的情况: ```c++ template <class I> struct iterator_traits { typedef typename I::value_type value_type; }; template <class T> struct iterator_traits<T*> { typedef T value_type; }; template <class T> struct iterator_traits<const T*> { typedef T value_type; }; ``` 迭代器最常用的相应型别有五种:value type、difference type、pointer、reference、iterator categoly。 ```c++ 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; }; ``` 迭代器类别分为五种: * Input Iterator:只读(read only); * Output Iterator:唯写(write only); * Forward Iterator:允许“写入型“算法进行读写操作; * Bidirectional Iterator:可双向移动; * Random Access Iterator:支持 `p+n`,`p-n` 等操作;