个人网站此文地址:http://jingyile.gotoip2.com/%E5%88%9D%E8%AF%86stl/
STL(Standard Template Library) 标准模板库
百度百科上将其分为六个部分:容器(containers)、迭代器(iterators)、空间配置器(allocator)、配接器(adapters)、算法(algorithms)、仿函数(functors)。
我们的C++课本上主要介绍了四种基本组件:容器(container)、迭代器(iterator)、函数对象(function object)、算法(algorithm)。
容器:即容纳,包含一组元素的对象。常用的vector、deque、list等
迭代器:应该是最不好理解也最重要的一个了,迭代器提供了顺序访问容器中每个元素的方法,支持"++"和"*"运算符,有些迭代器还支持"--"运算符,作用顾名思义。很明显,指针也具有同样的特性,因此指针本身是一种迭代器,迭代器是泛化的指针。
指针可以指向内存中的一个地址,通过这个地址就可以访问到相应的内存单元;
而迭代器更为抽象,它可以指向容器中的一个位置,我们不必关心这个位置对应的真正的物理地址,只需要通过迭代器访问这个位置的元素。
通俗的来说,迭代器是算法和容器的“中间人”。
算法:STL包括了70多个算法,覆盖面很广且具有统一性,可以广泛用于不同的对象和内置的数据类型。
函数对象:一个行为类似函数的对象,可以像调用函数一样调用。
任何普通的函数和重载了"( )"运算符的类的对象都可以当做函数对象使用。
下面这个小例子涉及到了这四种基本组件。
#include<iostream> #include<vector> #include<algorithm> #include<iterator>//使用独立于STL容器的迭代器 #include<functional>//使用STL的函数对象 using namespace std; int main() { const int N=5; vector<int> s(N); for(int i=0;i<N;i++) cin>>s[i]; transform(s.begin(),s.end(),ostream_iterator<int>(cout," "),negate<int>()); cout<<endl; return 0; }
ostream_iterator是一个输出迭代器的类模板,上面关联到的输出流cout和分隔符" "都是通过构造函数提供的。
negate是一个类模板,它重载了"()"运算符,接收一个参数,该运算符返回该参数的相反数。下面给出transform算法的一种实现
template<class InputIterator,class OutputIterator,class UnaryFunction> OutputIterator transform(InputIterator first,InputIterator last,OutputIterator result,UnaryFunction op) { for(;first!=last;++first,++result) *result=op(*first); return result; }即顺序遍历first和last两个迭代器所指向的元素,将每个元素的值作为函数对象op的参数,将op的返回值通过迭代器result顺序输出。
遍历完成后,result迭代器指向的是输出的最后一个元素的下一个位置,transform会将该迭代器返回。(上面的例子忽略了此返回值)。
关于求5个整数的相反数,常规做法应该是这样:
#include <iostream> using namespace std; int main() { int a[5]; for(int i=0;i<5;i++) cin>>a[i]; for(int i=0;i<5;i++) cout<<(-1)*a[i]<<" "; cout<<endl; return 0; }
上面的negate类模板,也可以直接用自己定义的求相反数函数代替,其效果是一样的。
#include<iostream> #include<vector> #include<algorithm> #include<iterator>//使用独立于STL容器的迭代器 #include<functional>//使用STL的函数对象 using namespace std; int fx(int x) { return (-1)*x; } int main() { const int N=5; vector<int> s(N); for(int i=0;i<N;i++) cin>>s[i]; //transform(s.begin(),s.end(),ostream_iterator<int>(cout," "),negate<int>()); transform(s.begin(),s.end(),ostream_iterator<int>(cout," "),fx); cout<<endl; return 0; }