模板使得算法独立于存储的数据类型。
迭代器使得算法独立于使用的容器类型。
迭代器类型
- 输入迭代器
- 输出迭代器
- 正向迭代器
- 双向迭代器
- 随机访问迭代器
迭代器具有层级结构: - 正向迭代器具有输入输出迭代器的全部功能,同时有自己的功能。
- 双向迭代器具有输入输出迭代器的全部功能,同时还有自己的功能。
- 随机访问迭代器具有正向迭代器的全部功能,同时还有自己的功能。
每个容器都定义了一个类级typedef名称–iterator,因此vector< int >类的迭代器类型为vector< int >::iterator,该迭代器为随机迭代器,具有所有迭代器的功能。而list< int >::iterator为双向迭代器。
STL算法可以使用任何满足其要求的迭代器实现。
指向int类型的常规指针是一个随机访问随机迭代器模型。
将指针用作迭代器
迭代器是广义指针,而指针满足所有迭代器的要求。迭代器是STL算法的接口,而指针是迭代器,因此STL算法可以使用指针来对基于指针的非STL容器进行操作,例如,可将STL算法用于数组。
C++将超尾的概念用于数组,使得可以将STL算法用于常规数组。
输出迭代器之ostream_iterator
#include< iterator >
ostream_iterator<int, char> out_int(cout, " ");
out_int迭代器现在是一个接口,
- 第一个模板参数(int)指出了被发送到输出流的数据类型;
- 第二个参数(char)指出了输出流使用的字符类型(另一个可用的是wchar_t)。
- 构造函数的第一个参数(cout)指出了要使用的输出流
- 最后一个字符串参数是在发送给输出流的每个数据项之间的分隔符。
#include <iostream>
#include<algorithm>
#include<iterator>
#include<string>
#include<vector>
using namespace std;
int main(void) {
int nums[] = {22,3,5,1,9,0,-9,99,-20};
char chs[] = { 'b','d','a','l','c','e' };
int len_int = sizeof(nums) / sizeof(int);
int len_char = sizeof(chs) / sizeof(char);
//使用sort()函数对数组进行排序
sort(nums, nums + len_int);
sort(chs, chs + len_char);
ostream_iterator<char, char> out_char(cout, " ");
ostream_iterator<int, char> out_int(cout, " ");
*out_int++ = 666;//相当于cout<< 666 << " ";
cout << "" << endl;
copy(nums, nums + len_int,out_int);//-20 -9 0 1 3 5 9 22 99
cout << "" << endl;
copy(chs, chs + len_char, out_char);//a b c d e l
vector<char> vec(len_char);
copy(chs, chs + len_char, vec.begin());
cout << endl << "反向迭代器:" << endl;
//rbegin和end返回值相同,但是类型不同(reverse_iterator和iterator),同样,rend和begin的返回值相同
copy(vec.rbegin(), vec.rend(), out_char);
return 0;
}
结果:
666
-20 -9 0 1 3 5 9 22 99
a b c d e l
反向迭代器:
l e d c b a
插入迭代器(输出迭代器)
- back_insert_iterator,将元素插到容器末尾,只适用于在尾部快速插入的容器(在尾部插入元素时使用固定时间O(1))
- front_insert_iterator,将元素插入到容器前端。只适用于在首部快速插入的容器(vector不适用,但list适用)
- insert_iterator,插入到insert_iterator构造函数的参数的指定的位置前。
#include <iostream>
#include<string>
#include<iterator>
#include<vector>
#include<algorithm>
using namespace std;
void output(const string & s) {
cout << s <<" ";
}
int main(void) {
string s1[4] = { "fine","fish","fashion","fate" };
string s2[2] = { "busy","bats" };
string s3[2] = { "silly","singers" };
vector<string> words(4);
copy(s1, s1 + 4, words.begin());
for_each(words.begin(), words.end(), output);
cout << "" << endl;
//back_insert_iterator的构造函数将假设传递给他的类型有一个push_back()方法。
back_insert_iterator<vector<string> > back_ins(words);
copy(s2, s2 + 2, back_ins);
for_each(words.begin(), words.end(), output);
cout << "" << endl;
//insert_iterator的构造函数还需要一个指示插入位置的参数
insert_iterator<vector<string> > ins(words, words.begin()+1);
copy(s3, s3 + 2, ins);
for_each(words.begin(), words.end(), output);
cout << "" << endl;
return 0;
}