标准模板库包括三种泛型:容器、迭代器和算法。
容器
容器是一种包含多个元素的数据结构,这些元素通常具有相同的类型。容器的实现可以多种多样,然后真正具有实际应用意义的容器并不多,它们包含在STL中,这些容器有:deque、list、map、multimap、set、multiset、stack、queue、priority_queue以及vector。
STL容器实现为模板类。大多数容器具有相同的操作方法,但是各自实现不同,比如默认构造器,复制构造器,析构器,empty(), max_size(), size(), swap(), operator=,另外,除了priority_queue容器,其他容器还包含六个关系运算符(<, <=, !=, ==, >=, >)。
存储在容器内的类型可以是任意类型,但是这些类型必须支持默认构造器,析构器和复制运算。有些编译器可能还要求实现关系运算符重载,虽然程序用不到这些。当然,数据成员如果是指针的话,还必须实现复制构造和operator=函数,因为插入操作使用的是元素的副本而不是元素自身。
迭代器
迭代器用于引用存储在容器中的某个元素,所以它其实是一个指针。所以,通过迭代器可以访问容器中的元素并对元素进行某些操作。
算法
STL提供了大约70种泛型函数,这些泛型函数即算法,可以应用到STL容器以及数组上。
函数对象
函数调用操作符“()” 可以看成跟其他操作符一样,这样“()”操作符可以被重载。包含函数调用操作符定义的对象称为函数对象。函数对象的行为就跟函数一样。
看一个具体的例子
class square{
public:
square() {
}
double operator() (double x) {
return x*x;
}
};
这段代码中,square类定义中重载了函数调用操作符,实现对输入参数求平方并返回结果。
调用代码如下
double squaresum(square s, int n, int m) {
double res = 0;
if( n <= m)
for(int i = n; i <= m; i++) res += s(i);
return res;
}
以上代码中,给函数对象传入一个输入参数,这个参数将会使函数调用操作符的输入参数。
当然也可以不重载函数调用操作符,如下代码所示
class square {
public:
square() {
}
double eval (double x) {
return x*x;
}
};
调用代码则为
double squaresum (square s, int n, int m) {
double res = 0;
if (n <= m)
for (int i = n; i <= m; i++)
res += s.eval(i);
return res;
}
测试代码为
cout << squaresum(square(), 1, 3) <<endl;
注意:这里测试代码要求square类实现自定义构造函数,这样square()可以构造一个函数对象。
STL中自带有一些函数对象。
unary_function
标准一元函数对象的基类,在一元函数对象中,operator()只能有一个参数。
unary_function是基类,它没有定义operator()方法,而是有派生类来实现。unary_function的定义为
template <class Arg, class Result>
struct unary_function {
typedef Arg argument_type;
typedef Result result_type;
};
下面给出一个简单的例子来说明用法
// unary_function example
#include <iostream> // std::cout, std::cin
#include <functional> // std::unary_function
template<class IN, class OUT>
struct IsOdd : public std::unary_function<IN, OUT> {
bool operator() (IN number) {return (number%2!=0);}
};
int main () {
IsOdd<int, bool> IsOdd_object;
IsOdd<int, bool>::argument_type input;
IsOdd<int, bool>::result_type result;
std::cout << "Please enter a number: ";
std::cin >> input;
result = IsOdd_object (input);
std::cout << "Number " << input << " is " << (result?"odd":"even") << ".\n";
return 0;
}