1、函数模板
template void name (T ...)
其中typename也可以换成class。
(1)可以多参template<class T1, class T2>
(2)模板中形参名可以不必是唯一的。
(3)如果调用了一个带用户自定义类型的模板,并且该模板用到了函数或运算符,那么这些函数和运算符必须被这个用户定义类型重载,否则运行出错
(4)如果一个普通函数和一个函数模板特化跟调用函数匹配度相同,那么这个普通函数会被调用。
2、类模板
也叫参数类型。 template class A {...}
使用: A a;
(1)类模板的成员函数的定义就是函数模板,所以出现在类模板定义外的成员函数的定义一定要加template,如:
template void A::B(...)
(2)类模板的所有成员函数必须在头文件中实现,不能在.cpp文件中实现。否则调用这个函数时会报错“无法解析的外部符号”
3、非类型参数和默认类型参数
非类型参数(在类中可以使用) template<typename T, int i>
默认类型参数 template
(1)有默认类型参数,使用时可以直接 A<> a 等同于 A a
(2)默认类型参数必须在模板参数列表最右侧(尾部)。
当有多个默认类型参数,其中一个不在最右侧,那么该参数右边所有的参数都会被忽略。
注意这里与默认实参不同,默认实参不在最右侧会报错,而默认类型参数则不会。
4、显示特化
如果一个特定的用户定义类型不能使用类模板或者需要有特定的处理,那么久可以为这个特定类型定义一个现实的类模板特化。
template<> class A {...}
新类会对原模板完全覆盖,它没有使用原来类模板的任何内容甚至可以包含不同的成员。
5、模板与继承
类模板可以从类模板特化派生得到
类模板可以从非类模板类派生得到
类模板特化可以从类模板特化派生得到
非类模板类可以从类模板特化派生得到
6、模板与友元
假设模板template class X
友元1: friend void f1() 是X,X,X<...>等的友元
友元2:friend void f2(X &) 那么f2(x &)只是X的友元
(1)可以将一个类的成员函数声明为一个类模板的友元,如:
friend void A::f3() 类A的f3函数是友元
7、模板和静态成员
每一个由相同类模板实例化产生的类模板特化都有它自己的类模板静态数据成员的副本。
一个模板类特化产生的所有对象都共享一个静态数据成员。
每个类模板特化都得到一份属于自己的类模板静态成员函数的副本。