关于模板的基本知识

C++标准库的开发,几乎所有东西都被设计为模板形式,所以掌握Template技术是学习标准库的基础。

回顾下Template,它是一种针对“一个或多个尚未明确类型”所编写的函数或类别,其中共性是逻辑相同,异处在于该逻辑中使用到的类型需要用户自己设定。

当然,我们在使用Template时,可以“显式explicitly”或“隐式implicitly”地将类型当做参数来传递

最简单的:

template <class T>    // 因为class尚未确定,暂时用T代替
inline const T& max (const T& a, const T& b)
{
       return a < b? b : a;      
}

Template并非一次编译就能够产生出所有可用类型的代码,而是需要用户进行设定,设定完之后编译器才能根据用户设定的值进行产生合适的类型,来产生调用操作。

关于Template函数可移植性的操作方式就是在头文件中以inline function来实现。

 

接下来需要对template的几个重要特性进行说明:

-----------------------------------------------------定义函数模板-----------------------------------------------------

1. 模板形参表:

定义的这些形参就像函数形参表,该形参表定义了特定类型的局部变量,但并不初始化,直到运行时再提供实参来初始化形参。

模板形参可以是:表示类型的类型形参(type)、表示常量表达式的非类型形参(non-type)

类型形参的关键字是class或typename,其实两个关键字没什么大区别。

2. 使用函数模板:

使用函数模板时,编译器会推断哪个模板实参绑定到模板形参,一旦编译器确定了实际的模板实参,那么这个编译器就实例化了函数模板的一个实例。

所以,是由编译器来承担为我们使用的每种类型而编写函数的单调工作。

3. inline函数模板:

函数模板加上inline的方式和一般函数类似,但写的时候注意,是放在模板形参之后,函数返回类型之前:

template <typename T>

inline T play(const T& t1, const T& t2);

-----------------------------------------------------定义类模板-----------------------------------------------------

1. 使用类模板:

必须为模板形参显式的指定实参:

Queue<int> qi;

Queue<vector<double>> qc;

Queue<string> qs;

实例化工作还是由编译器来完成。

模板形参:

就好像一般的函数形参,形参名字为任意设计,名字前需要添加“类型”。

区别在于,形参可以是类型形参(一个未知类型),也可以是非类型形参(一个未知值)。

模板类型形参:

由关键字class或typename构成,这两个关键字作用基本相同,只是typename比class更直观。

对于模板内部定义类型成员,但编译器无法知道这个成员是一个值还是类型:

template <typename T>
void Function(T* t)
{
    T::size_type *p;    // 这个size_type是自定义的,所以编译器默认是收成员,而不是类型成员
    
    // 除非
    typename T::size_type *pi;
}

所以,typename还是给类型成员指定是类型还是数据。

非类型模板形参:

假如模板的类型不是一个类型,而是一个数据,该形参是用来作为模板内部的常量值。

 

那么我们如何来编写一个泛型程序呢?这取决于某段代码是否是类型不确定的。比如一个比较操作:

if (v1 < v2) return -1;

if (v1 > v2) return 1;

return 0;

那么v1与v2有很多种可能,常量或类型?? 如果是常量则比较简单,但如果是类型,是否重载了<与>运算符的操作呢?

 

 模板实例化:

 模板如果看成是图纸,那么实例化就是按照图纸制作出实际产品,这需要用户提供模板实参,由编译器来完成实例化过程。

1. 实例化类时,编译器首先会自动创建用户指定名字的类。实例化时,指定模板实参是必须的。

2. 但实例化函数模板时,根据用户填入的实参,编译器可能会进行自动判断实参类型。

 

成员模板:

一个类的成员函数也可以是模板函数,但不可以是虚函数,也不能有缺省参数:

class MyClass
{
    // ....
    template <class T>
    void fun(const T &t);
}
posted @ 2014-04-21 11:38  大卫酱_David  阅读(278)  评论(0编辑  收藏  举报