C++primer--16章--模板与泛型编程

C++primer--16章--模板与泛型编程

gaowanchen photo By gaowanchen Comment Permalink

泛型编程:独立于任何特定类型的方式编写代码

目录

模板定义

函数模板

  1. 定义一个函数模板
1 template<typename TYPE>//typename也可以用class代替,typename是较新的标准
2 int compare(const TYPE &v1,const TYPE &v2)
3 {
4         return v1<v2? -1:1;
5 }
  1. 使用一个函数模板
    compare(1,2);//编译器会自动实例化compare

  2. inline函数模板
    要注意的是inline关键词在模板参数列表之后
    template<typename TYPE> inline TYPE fun(const TYPE v1,const TYPE v1);

类模板

  1. 定义一个类模板
 1 template<typename TYPE> 
 2 class QUEUE
 3 {
 4     public:
 5         QUEUE();//构造函数
 6         TYPE &front();
 7         const TYPE &front() const;//重载
 8         void push (const TYPE &);
 9         void pop();
10         bool empty() const;
11     private:
12 };
  1. 使用一个类模板

需要注意的是,使用类模板需要显式的指定实参

QUEUE<int> queue_int //实例化一个QUEUE<int>类型的实例queue_int
QUEUE<vector<double>> queue_vector_double

在模板定义内部指定类型

除了定义数据成员函数成员以外,类还可以定义类型成员,如果我们要在函数模板内部使用这样的类型,必须告诉编译器我们正在使用的名字指的是一个类型。

1 template<class Parm,class U>
2 Parm fcn(Parm * array,U value)
3 {
4     typename Parm::size_type *p //告诉编译器将成员当做类型
5 }

非类型模板形参

模板的形参不必都是类型!

函数模板

1 //初始化一个数组为全0
2 template<class TYPE ,size_t N>
3 void array_init(TYPE (&parm)[N])
4 {
5     for(size_t i=0;i!=N;++i)
6     {
7         parm[i]=0;
8     }
9 }

编译器将根据数组的具体情况,计算N的值并实例化不同版本的函数

类型等价性

对非类型形参,如果求值结果相同,则被认为是等价的

1 int x[42];
2 const int sz=40;
3 int y[sz+2];
4 array_init(x);//array_init<int,42>
5 array_init(y);//array_init<int,42>

注意

  1. 虽然模板对一切类型有效,但是实例化后的结果可能是非法的,所以在编写前总是会假定可能使用的类型。
  2. 在编写代码的时候,对实参类型的要求尽可能少是比较有益的
  3. 两个重要原则:模板的形参是const引用,函数体中的测试只用<(可以减少对类型的要求)

发现错误的阶段

  1. 编译模板定义本身
  2. 编译器检查模板的使用时
  3. 实例化时
  4. 在链接的时候

实例化

模板相当于一个蓝图,编译器根据他来产生制定的类或者函数,这一过程称为实例化

类的实例化