1.反向迭代器(reverse_iterator) 又称“逆向迭代器”,其内部重新定义了递增运算符(++)和递减运算符(–),专门用来实现对容器的逆序遍历。
reverse_iterator 模板类中共提供了 3 种创建反向迭代器的方法,这里以 vector 容器的随机访问迭代器作为基础迭代器为例。
-
调用该类的默认构造方法,即可创建了一个不指向任何对象的反向迭代器,例如: std::reverse_iterator<std::vector::iterator> my_reiter; 由此,我们就创建好了一个没有指向任何对象的 my_reiter 反向迭代器。 -
当然,在创建反向迭代器的时候,我们可以直接将一个基础迭代器作为参数传递给新建的反向迭代器。例如: 纯文本复制 //创建并初始化一个 myvector 容器 std::vector myvector{1,2,3,4,5}; //创建并初始化 my_reiter 迭代器 std::reverse_iterator<std::vector::iterator> my_reiter(myvector.end()); -
除了第 2 种初始化方式之外,reverse_iterator 模板类还提供了一个复制(拷贝)构造函数,可以实现直接将一个反向迭代器复制给新建的反向迭代器。比如: 纯文本复制 //创建并初始化一个 vector 容器 std::vector myvector{1,2,3,4,5}; //调用复制构造函数初始化反向迭代器的 2 种方式 std::reverse_iterator<std::vector::iterator> my_reiter(myvector.rbegin()); //std::reverse_iterator<std::vector::iterator> my_reiter = myvector.rbegin();
reverse_iterator 模板类还提供了 base() 成员方法,该方法可以返回当前反向迭代器底层所使用的基础迭代器。
2.安插型迭代器(inserter或者insert_iterator) 通常用于在容器的任何位置添加新的元素,需要注意的是,此类迭代器不能被运用到元素个数固定的容器(比如 array)上。
back_insert_iterator 在指定容器的尾部插入新元素,但前提必须是提供有 push_back() 成员方法的容器(包括 vector、deque 和 list)。 front_insert_iterator 在指定容器的头部插入新元素,但前提必须是提供有 push_front() 成员方法的容器(包括 list、deque 和 forward_list)。 insert_iterator 在容器的指定位置之前插入新元素,前提是该容器必须提供有 insert() 成员方法。
C++ STL 标准库中,提供有 push_back() 成员方法的容器包括 vector、deque 和 list。 C++ STL 标准库中,提供有 push_front() 成员方法的容器,仅有 deque、list 和 forward_list。 需要说明的是,该类型迭代器的底层实现,需要调用目标容器的 insert() 成员方法。但幸运的是,STL 标准库中所有容器都提供有 insert() 成员方法,因此 insert_iterator 是唯一可用于关联式容器的插入迭代器。
和反向迭代器不同,back_insert_iterator 插入迭代器的定义方式仅有一种,其语法格式如下: std::back_insert_iterator back_it (container); 其中,Container 用于指定插入的目标容器的类型;container 用于指定具体的目标容器。
举个例子: //创建一个 vector 容器 std::vector foo; //创建一个可向 foo 容器尾部添加新元素的迭代器 std::back_insert_iterator< std::vector > back_it(foo); std::insert_iterator insert_it (container,it); 其中,Container 表示目标容器的类型,参数 container 表示目标容器,而 it 是一个基础迭代器,表示新元素的插入位置
3.流迭代器(istream_iterator / ostream_iterator) 流缓冲区迭代器(istreambuf_iterator / ostreambuf_iterator) 输入流迭代器用于从文件或者键盘读取数据;相反,输出流迭代器用于将数据输出到文件或者屏幕上。 输入流缓冲区迭代器用于从输入缓冲区中逐个读取数据;输出流缓冲区迭代器用于将数据逐个写入输出流缓冲区。
输入流缓冲区迭代器(istreambuf_iterator):从输入流缓冲区中读取字符元素; 输出流缓冲区迭代器(ostreambuf_iterator):将连续的字符元素写入到输出缓冲区中。
流缓冲区迭代器和流迭代器最大的区别在于,前者仅仅会将元素以字符的形式(包括 char、wchar_t、char16_t 及 char32_t 等)读或者写到流缓冲区中,由于不会涉及数据类型的转换,读写数据的速度比后者要快。
- 通过调用 istreambuf_iterator 模板类中的默认构造函数,可以创建一个表示结尾的输入流缓冲区迭代器。要知道,当我们从流缓冲区中不断读取数据时,总有读取完成的那一刻,这一刻就可以用此方式构建的流缓冲区迭代器表示。
举个例子: std::istreambuf_iterator end_in; 其中,<> 尖括号中用于指定从流缓冲区中读取的字符类型。
- 当然,我们还可以指定要读取的流缓冲区,比如:
std::istreambuf_iterator in{ std::cin }; 除此之外,还可以传入流缓冲区的地址,比如: std::istreambuf_iterator in {std::cin.rdbuf()}; 其中,rdbuf() 函数的功能是获取指定流缓冲区的地址。 无论是传入流缓冲区,还是传入其地址,它们最终构造的输入流缓冲区迭代器是一样的。
创建输出流缓冲区迭代器的常用方式有以下 2 种:
-
通过传递一个流缓冲区对象,即可创建一个输出流缓冲区迭代器,比如: std::ostreambuf_iterator out_it (std::cout); 同样,尖括号 <> 中用于指定要写入字符的类型,可以是 char、wchar_t、char16_t 以及 char32_t 等。 -
还可以借助 rdbuf(),传递一个流缓冲区的地址,也可以成功创建输出流缓冲区迭代器: std::ostreambuf_iterator out_it (std::cout.rdbuf());
4.移动迭代器(move_iterator) 此类型迭代器是 C++ 11 标准中新添加的,可以将某个范围的类对象移动到目标范围,而不需要通过拷贝去移动。 move_iterator 迭代器适配器,又可简称为移动迭代器,其可以实现以移动而非复制的方式,将某个区域空间中的元素移动至另一个指定的空间。
如何将const_iterator转换为iterator类型迭代器? 对于 C++ STL 标准库中的这 4 种基础迭代器来说,C++ 编译器的隐式转换仅支持以下 2 种情况: 将 iterator 类型的迭代器隐式转换为 const_iterator 类型的迭代器; 将 reverse_iterator 类型的迭代器隐式转换为 const_reverse_iterator 类型的迭代器。 注意,以上 2 种隐式转换是单向的,即编译器只支持从 iterator 转换为 const_iterator,从 reverse_iterator 转换为 const_reverse_iterator,但不支持逆向转换。
//将 const_iterator 转换为 iterator advance(iter, distance<cont::const_iterator>(iter,citer)); //将 const_reverse_iterator 转换为 reverse_iterator advance(iter, distance<cont::const_reverse_iterator>(iter,citer));
其中,citer 为指向某个容器(比如 cont)任意位置的 const_iterator(或者 const_reverse_iterator)类型迭代器,而 iter 通常初始为指向 cont 容器中第一个元素的 iterator(或者 reverse_iterator)类型迭代器。通过套用此格式,最终 iter 会变成一个指向和 citer 一样的 iterator(或者 reverse_iterator)类型迭代器。 注意,在使用 distance() 函数时,必须额外指明 2 个参数为 const 迭代器类型,否则会因为传入的 iter 和 citer 类型不一致导致 distance() 函数编译出错。 该实现方式的本质是,先创建一个迭代器 citer,并将其初始化为指向容器中第一个元素的位置。在此基础上,通过计算和目标迭代器 iter 的距离(调用 distance()),将其移动至和 iter 同一个位置(调用 advance()),由此就可以间接得到一个指向同一位置的 iter 迭代器。
|