标准模板库STL
标准模板库 不是面向对象编程,而是泛型编程。
迭代器
为什么需要迭代器
C++的模板使得算法独立于容器中存储的数据类型,但仍然与容器关联。为了使算法独立于容器本身的数据结构,引入了迭代器,迭代器是遍历容器中的值的通用表示。
迭代器的通用功能
- 解除引用:*p
- 把一个迭代器赋给另一个:p=q
- 比较:p==q,p!=q
- 遍历:p++,++p
迭代器类型iterator_category(概念描述)
STL使用术语概念(concept)来描述一系列的要求,使用术语改进(refinement)来表示概念上的继承,概念的具体实现称为模型(model)。
- 输入迭代器:单向迭代器,只可以用++遍历,可以读取
- 输出迭代器:单向迭代器,只可以用++遍历,可以修改
- 正向迭代器:可多次通行,只可用++遍历,可读取和修改
- 双向迭代器:可多次通行,可用++和–遍历,可读取和修改
- 随机访问迭代器:有双向迭代器的所有特征,同时可以随机访问
//定义在<iterator>中的iterator_traits类的iterator_category可以是以下5者之一
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{};
5种迭代器类型分别支持的操作:
各种容器iterators的iterator_category
stack、queue、priority_queue没有iterator
//测试程序
void _display_category(random_access_iterator_tag)
{
cout<<"random_access_iterator"<<endl;
}
template<typename T>
void display_category(T itr)
{
typename iterator_traits<T>::iterator_category cagy;
_display_category(cagy);
cout<<typeid(itr).name()<<endl;
}
display_category(array<int,10>::iterator());
迭代器类型 | 容器 |
---|---|
random access | array、vector、deque、 |
bidirectional | list、set、multiset、map、multimap |
forward | forward_list、unordered_set、unordered_map、unordered_multiset、unordered_multimap |
将指针用作迭代器
指针满足所有的迭代器要求,而且STL算法是基于迭代器的,因此STL算法可以使用指针来对基于指针的非STL容器进行操作。
例如:将STL函数sort( )用于数组,C++支持将超尾概念用于数组
double Receipts[100];
sort(Receipts,Receipts+100);
STL预定义迭代器
ostream_iterator
是输出迭代器概念的一个模型。
#include <iterator>
int casts[10] = {6,7,2,9,4,11,8,7,10,5};
vector<int> dice[10];
copy(casts,casts+10,dice.begin());
ostream_iterator<int,char> out_iter(cout," ");
*out_iter = 15;
copy(dice.begin(),dice.end(),out_iter);
copy(dice,begin(),dice.end(),ostream_iterator<int,char>(cout," "));
istream_iterator
是输入迭代器概念的一个模型。第一个模板参数表示要读取的数据类型,第二个模板参数表示输入流使用的数据类型,使用构造函数参数cin表示使用由cin管理的输入流(也可以使用文件流等),省略构造函数参数表示输入失败。
copy(istream_iterator<int,char>(cin),istream_iterator<int,char>(),dice.begin());
reverse_iterator
- 反向迭代器,执行递增操作将导致递减
- rbegin()返回一个指向超尾的反向迭代器,rend()返回一个指向第一个元素的反向迭代器
- 对解除引用的实现为先递减再解除引用
例子:反向打印
copy(dice.rbegin(),dice.rend(),ostream_iterator<int,char>(cout," "));
back_insert_iterator
- 将元素插入容器尾部,只用于允许在尾部快速插入的容器
- 将容器类型作为模板参数,将实际的容器标识符作为构造函数参数
back_insert_iterator<vector<int>> back_iter(dice);
front_insert_iterator
- 将元素插入容器前段,只用于允许在前段快速插入的容器
- 将容器类型作为模板参数,将实际的容器标识符作为构造函数参数
front_insert_iterator<vector<int>> front_iter(dice);
insert_iterator
- 将元素插入容器指定位置
- 将容器类型作为模板参数,将实际的容器标识符和插入位置作为构造函数参数
insert_iterator<vector<int>> insert_iter(dice,dice.begin());