标准模板库
百度百科上将其分为六个部分:容器(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;
}