模板可能是c++中最强大最强大却最少被使用(或被理解)的特性之一了;我们可以用模板来定义一种适用于不同类型的对象的行为
这就像是用#define定义的一个返回两个数中最大值的宏函数那样#define MAX_NUM(a, b) ((a) > (b) ? (a) : (b))
这里的a,b可以是int类型、也可以是其他类型;与“”宏函数不同的是宏不是类型安全的,而模板是类型安全的
- 模板函数/类声明语法
1 | template <参数列表> |
参数列表中包含关键字typename,它定义了参数objectTyep,objectType是一个占位符,当对象实例化模板时(创建类实例时)将使用指定的对象类型替换它:
1 | //模板函数 |
上述代码中实例化Template类时,将T1指定为int类型,将T2指定为float类型(显式指定)。
第一次调用模板函数时,将T指定为float类型;第二次调用时却没有指定类型,但这样也是正确的,这时候,模板函数会自动判断数据的类型(隐式指定)。
不过,对于模板类,必须要显式指定其类型。
声明包含多个参数的模板
声明包含多个参数的模板时, 参数之间用逗号隔开:template < typename T1, typename T2,...., typename Tn >
声明包含默认参数的模板
声明包含默认参数的模板时, 可将它初始化成默认类型:template < typename T1 = int, ... , typename tn = int >
*模板类和静态成员
在普通的类中,类成员被定义成静态的话,该静态成员被所有实例共享;
在模板类中,也类似这样,只不过是被同类型的具体化的实例所共享的:
1 | template <typename T> |
上述代码中两次输出结果分别是1997、917。你该懂了吧
c++中的静态成员变量
在c++的类中,如果存在静态成员变量的话,必须对它进行初始化,格式如下:<数据类型><类名>::<静态数据成员名> = <值>
模板类中的静态成员变量的初始化格式:(参考上述代码的初始化)
template<参数> <数据类型><类名<参数>>::<静态数据成员名> = <值>
c++11
使用static_assert执行编译阶段的检查(类似assert宏)
static_assert是c++11中新加的功能(有的编译器不支持),它是一种编译断言,能够在不满足条件时禁止编译。使用格式:static _assert(表达式, "表达式为假时输出的错误信息")
1 | template <typename T> |
上述代码编译时会报错。