|
函数对象在使用STL时非常重要,你需要熟悉这样的编码形式。在使用STL时,经常需要把函数对象作为算法的输入参数,或着实例化一个容器(container)时的输入参数。
2.3 模板(Template)
2.3.1函数模板
请看下面的代码:
void swap(int& a, int& b)
{
int tmp = a;
a = b;
b = tmp;
}
这个函数swap很简单:把两个整数的值交换一下。但当你写一个大程序时,经常需要交换float、long、char等变量,甚至如上面定义的shape变量,这时候你就需要把上面的代码修改一下,适应各自的参数类型,然后拷贝到很多处各自需要的地方。一旦需要对这块代码做些改动的时候,就必须把所有用到这块代码的地方一一做相应的修改,其烦无比!
解决这个问题的方法就是用模板(template):
template <class T>
void swap(T& a, T& b)
{
T tmp = a;
a = b;
b = tmp
}
注意这里T是任意的类型名字。看例子:
int a = 3, b =5;
shape MyShape, YourShape;
float fa = 3.01, fb = 5.02;
swap(a , b); //交换整数
swap(MyShape, YourShape); //交换自定义类的两个对象的值
swap(fa, fb); //交换浮点数
还可以看看两个函数模板例子:
template <class T>
T& min(T& a, T& b) // 取两个元素中的最小者
{
return a < b ? a : b;
}
template <class T>
void pritn_to_cout(char* msg, T& obj) // 把一个元素输出到cout上
{
cout << msg << “: “ << obj << endl;
}
使用后者时,要求类型T中定义了put-to操作符(operator <<)。
2.3.2类模板
创建类模板的动机和容器类的使用是密切相关的。比如一个容器类栈(stack),定义者并不关心栈中对象的类型,而使用stack者自己指定到底包含什么对象类型。
下面看一个向量(vector)例子:
template <class T>
class vector
{
T* v;
int sz;
public:
vector(int s) { v = new T[sz = s]; }
~vector() { delete [] v; }
T& operator[] (int i) { return v[i]; }
int get_size() { return sz; }
};
现在你可以实例化不同类型的vector容器了:
vector<int> int_vector(10);
vector<char> char_vector(10);
vector<shape> shape_vector(10);
2.3.3模板特化
也许在某些情况下,编译器对某种类型产生的模板代码不另你满意,你也可以为这种类型给出一个特定的实现,此之谓“模板特化(template specialization)”。比如,你想让shape类型的vector只包含一个对象,则可以特化vector模板如下:
class vector<shape>
{
shape v;
public:
vector(shape& s) : v(s) {}
shape& operator[] (int i) { return v; }
int get_size() { return 1; }
};
使用时:
shape MyShape;
vector<shape> single_shape_vector(MyShape);
STL中有时会需要定义特定类型的算法或容器实现。
3 STL概貌
|
