<utility.h>utility中只有模版类pair,和一些与之相关联得模版操作符,该模版类用来将两个对象合并为一个对象,当你想要一个函数返回两个值得时就比较方便了。
其中模版函数make_pair可以在必要时产生一个pair对象,该函数在检测参数时忽略掉所有CONST属性,所以不能依赖他产生包含一个或多个常量成员对象得pair对象。
测试文件:
#include "iostream"
#include "assert.h"
#include "utility"
using namespace std;
class Int
{
public:
Int(int v):val(v){}
Int(){val=0;}
bool operator==(Int x)const{return (val==x.val);}//仅重载==AND<就可以了,其他的库会帮我们完成
bool operator<(Int x) const{return (val<x.val);} //重载函数
private:
int val;
};
typedef pair<int ,char>pair_ic;
pair_ic p0;
typedef pair<Int,char>pair_id;
pair_id d0;
int main()
{
pair_ic p1=p0,p2(3,'a');
assert(p1.first==0);
assert(p1.second==0);
assert(p2.first==3);
assert(p2.second=='a');
assert(p2==make_pair((pair_ic::first_type)3,(pair_ic::second_type)'a'));
assert(p2<make_pair((pair_ic::first_type)4,(pair_ic::second_type)'a'));
assert(p2<make_pair((pair_ic::first_type)3,(pair_ic::second_type)'b'));
assert(p1!=p2);
Int a(2),b(3);
pair_id d0(a,'a');
pair_id d1(a,'b');
assert(d0!=d1);
assert(d0<=d1);
assert(d1>=d0);
return 0;
}
<iterator> 中定义了迭代器得使用方法,主要得模版类有:
插入迭代器
插入迭代器是一种迭代器适配器,带有一个容器参数,并生成一个迭代器,用于在指定的容器中插入元素。通过插入迭代器赋值时,迭代器将会插入一个新的元素。C++语言提供了三种插入器,其差别在于插入元素的位置不同:
istream_iterator<T> in(strm); | 创建从输入流strm中读取T类型对象的istream_iterator对象,strm是一个输入流 |
istream_iterator<T> in; | istream_iterator对象的超出末端迭代器 |
ostream_iterator<T> out(strm); | 创建将T类型的对象写到输出流strm的ostream_iterator对象 |
ostream_iterator<T> out(strm, delim); | 创建将T类型的对象写到输出流strm的ostream_iterator对象,在写入过程中使用delim作为元素的分隔符。delim是以空字符结束的字符数组 |
#include <iostream>
#include <vector>
#include <iterator>
using namespace std;
int main() {
istream_iterator<int> in_iter(cin);
istream_iterator<int> eof;
//vector<int> vec(in_iter, eof); //do the same work as following loop
vector<int> vec;
while (in_iter != eof)
vec.push_back(*in_iter++); //*in_iter可以取出输入流中得元素
vector<int>::const_iterator it = vec.begin();
for(; it != vec.end(); ++it)
cout<<*it<<endl;
return 0;
}
#include <iostream>
#include <iterator>
using namespace std;
int main() {
ostream_iterator<string> out_iter(cout, "/n");
istream_iterator<string> in_iter(cin), eof;
while (in_iter != eof)
*out_iter++ = *in_iter++;
return 0;
}
反向迭代器
反向迭代器是一种反向遍历容器的迭代器。也就是,从最后一个元素到第一个元素遍历容器。反向迭代器将自增(和自减)的含义反过来了:对于反向迭代器,++运算将访问前一个元素,而--运算则访问下一个元素。
(1)反向迭代器需要使用自减操作符:标准容器上的迭代器(reverse_iterator)既支持自增运算,也支持自减运算。但是,流迭代器由于不能反向遍历流,因此流迭代器不能创建反向迭代器。
(2)可以通过reverse_iterator::base()将反向迭代器转换为普通迭代器使用,从逆序得到普通次序。
测试:
#include <iostream>
#include <string>
#include <iterator>
#include <algorithm>
using namespace std;
int main() {
string str = "this 'sentence' is a test";
cout<<str<<endl;
string::iterator it1 = find(str.begin(), str.end(), '/'');
string::iterator it2 = find(++it1, str.end(), '/'');
cout<<string(it1, it2)<<endl;
string::reverse_iterator rit1 = find(str.rbegin(), str.rend(), '/'');
string::reverse_iterator rit2 = find(++rit1, str.rend(), '/'');
cout<<string(rit1, rit2)<<endl;
cout<<string(rit2.base(), rit1.base())<<endl;
getchar();
return 0;
}
不同的迭代器支持不同的操作集,而各种算法也要求相应的迭代器具有最小的操作集。因此,可以将算法的迭代器分为下面五类:
输入迭代器
(input iterator) 读,不能写。支持的操作集:==, !=, 前缀++, 后缀++, *, ->。例如,find, accumulate算法要求这类迭代器。 输出迭代器
(output iterator) 写,不能读。支持的操作集:前缀++, 后缀++, *(只能出现在赋值运算的左操作数上)。推出迭代器要求每个迭代器必须正好写入一次。例如,ostream_iterator是输出迭代器,copy算法使用这类迭代器。 前向迭代器(forward iterator) 读和写,支持输入迭代器和输出迭代器提供的所有操作,还支持对同一个元素的多次读写。例如,replace算法需要这种迭代器。 双向迭代器(bidirectional iterator) 读和写,除了支持前向迭代器的所有操作,还支持前缀--和后缀--,即支持双向遍历容器。例如,reverse算法要求这类迭代器。标准库容器中提供的迭代器都至少达到双向迭代器的要求。 随机访问迭代器(random-access iterator) 读和写。提供在常量时间内访问容器任意位置的功能。支持完整的迭代器操作集:1)关系运算:==, !=, <, <=, >, >=;2)算术运算:it + n, it - n, it += n, it -= n以及it1 - it2;3)下标运算:it[n],等价于*(it + n)。需要随机访问迭代器的泛型算法包括sort算法。例如,vector, deque, string迭代器是随机访问迭代器,用作访问内置数组元素的指针也是随机访问迭代器。
除了输出迭代器,其他类别的迭代器形成了一个层次结构:需要低级类别迭代器的地方,可使用任意一种更高级的迭代器。例如,对于需要输入迭代器的算法,可传递前向、双向或随机访问迭代器调用该算法。而反之则不行。注意:向算法传递无效的迭代器类别所引起的错误,无法保证会在编译时被捕获到。
map, set, list类型提供双向迭代器,而string, vector和deque容器上定义的迭代器都是随机访问迭代器,用作访问内置数组元素的指针也是随机访问迭代器。istream_iterator是输入迭代器,ostream_iterator是输出迭代器。
另外,虽然map和set类型提供双向迭代器,但关联容器只能使用这部分算法的一个子集。因为关联容器的键是const对象。因此,关联容器不能使用任何写序列元素的算法。只能使用与关联容器绑在一起的迭代器来提供用于读操作的实参。因此,在处理算法时,最好将关联容器上的迭代器视为支持自减运算的输入迭代器,而不是完整的双向迭代器。
<memory> 它以不同寻常得方式为容器中得元素分配存储空间,它同样也为某些算法执行期间产生得临时对象提供机制,主要模版类为:allocator由他产生容器得默认分配器,我们很少需要直接与分配器打交道,默认得分配器已经可以很好得为我们工作了,但它又包含在标准C++库中所定义得每个容器模版类得模版参数里。