码迷,mamicode.com
首页 > 其他好文 > 详细

STL模板_概念

时间:2015-10-15 22:04:00      阅读:212      评论:0      收藏:0      [点我收藏+]

标签:

模板和STL
一、模板的背景知识
1.针对不同的类型定义不同函数版本。
2.借助参数宏摆脱类型的限制,同时也因为失去的类型检查而引
入风险。
3.借助于编译预处理器根据函数宏框架,扩展为针对不同类型的
具体函数版本,一方面统一编写通用的算法和结构,另一方面
也具有函数调用的类型安全性。
4.通过编译器根据函数模板生成具体函数——类型参数化。
int add (int x, int y) { ... } // x和y是值参数
int a = 10, b = 20, c;
c = add (a, b);
template<typename T> // T是类型参数
T max (T x, T y) { ... }
max<int> (...);
max<double> (...);
模板更多是使用预定义模板:string/auto_ptr/list/QList
二、函数模板
1.函数模板代表一个函数族,虽然其外观类似于普通函数,但其
带有参数化的类型(类型参数)。编译器编译函数模板时将类
型参数编程具体类型,生成具体函数的二进制代码。
2.函数模板的定义
template<模板参数表>
返回类型 模板函数名 (调用参数表) { 模板函数体; }
模板参数表:typename 模板参数1, typename 模板参数2, ...
模板参数的命名规则与一般有效标识符的命名一样:以字母或下
划线开始,由字母、数字或下划线组成。
typename关键字也可以用class替换,但是这里的class并不表
示类,而且不用换成struct。
template<typename T>
T max (T x, T y) { ... }
template<class T>
T max (T x, T y) { ... }
max<Student> (...);
max<string> (...);
max<int> (...);
max<double> (...);
3.函数模板的使用
函数模板名<模板参数表> (调用参数表);
1)编译器根据调用函数模板时所提供的模板实参,将所调用的函
数模板编译成具体函数的过程,称为函数模板的实例化。
2)用于实例化函数模板的类型必须满足模板内部基于该类型的操
作。
3)函数模板的二次编译。编译器第一次看到函数的定义,因为不
知道其中的模板参数是什么类型,所以无法成生成二进制指令,
但是编译器会首先做与类型无关的语法检查,如果没有语法错误
,编译器会根据函数模板的定义生成一个内部表示。当编译器看
到对函数模板的调用语句时,将所提供的具体模板实参结合先前
生成的内部表示,产生具体函数的二进制指令。
4)对于函数模板一定要让编译器在看到调用语句的同时,也能看到该模板的定义代码,否则编译器无法完成第二次编译,也就无
法生成具体的函数代码。为此,最简单的做法是,将函数模板的定义放在头文件中,所有需要使用该函数模板的源文件都要包含
此头文件。
4.函数模板参数的隐式推断
5.函数模板的重载:在提供通过规则的同时,专门针对某些特殊
类型给出特殊的实现。
三、类模板
1.类的成员变量、成员函数(普通/静态/构造/析构/运算符)的返
回值/参数/局部变量,以及基类中的类型都可以参数化,这样的
模板就称为类模板。
2.定义类模板
template<模板参数表>
class 类模板名 { ... };
类模板的每个成员函数无论其是否带有类型参数,都是函数模板。如果在类模板的外部定义成员函数,必须按照函数模板的语法
定义它们。
tempalte<模板参数表>
返回类型 类模板名<模板参数表>::成员函数名 (调用参数表){...}
3.使用类模板
类模板并不是一个类型,只有当其余具体模板参数结合以后,才
会变成类,才是一个具体类型。类模板变成具体类的过程,叫做
类模板的实例化。
类模板名<模板参数表>
~~~~~~~~~~~~~~
类 -> 访问其静态成员、定义变量/创建对象
类模板只能显式实例化,不支持隐式推断。
编译期 运行期
类模板 -实例化-> 类 -实例化-> 对象
编译器 处理器
类模板的模板参数可以带有缺省值,而且参数缺省值必须靠右。
C++98中函数模板不可以带有缺省值,但是在C++2011中函数
模板也可以带有缺省值(-std=c++0x)。
4.类模板的实例化
1)类模板中,只有那些被调用的成员函数才会被实例化,即产生
二进制代码。
2)某些类型虽然并没有提供类模板所需要的全部功能,但照样可
以实例化该类模板,只要不直接或间接调用那些依赖于未提供功
能的成员函数即可。
5.类模板的静态成员变量,在该类模板的每个实例化类中,都有
一份独立的拷贝,并为该实例化类的所有实例化对象所共享。
6.类模板的递归实例化
用一个类模板的实例化类型实例化该类模板自身。用这种方法可
以很容易地构建在空间上具有递归结构的逻辑模型。
List<Array<int> > : 数组链表
Array<List<int> > : 链表数组
List<List<int> > : 二维链表
Array<Array<int> > : 二维数组
7.类模板的特化
1)通过特化类模板,可以优化针对某种特定类型的实现,或者克
服某种特定类型在实例化类模板时所表现出的不足。
2)特化一个类模板需要特化该类模板的所有成员函数——全类特化。
template<>
class 类模板名<特化所针对的模板参数> { ... };
全类特化的版本可以和基本版本完全不同。
3)如果类模板只有部分成员函数的实现与类型相关,那么也可以
只针对该成员函数进行特化——成员特化。
类模板成员函数的特化版本与其基本版本共享同一个声明,因此
特化版本与基本版本的函数原型,除了模板参数外,必须严格一致。
8.类模板的局部特化(偏特化)
1)类模板可以局部特化,即一方面为类模板指定特定的实现,另
一方面又允许用户对部分模板参数自行指定。
2)如果多个局部特化同等程度地匹配某个声明,那么该声明将因
二义性而导致歧义错误。
3)函数模板不支持局部特化。

STL模板_概念

标签:

原文地址:http://www.cnblogs.com/Neo-Lc/p/4883722.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!