模板概述¶
模板定义和使用¶
模板定义示例如下:
template <typename T>
T minimum(const T& lhs, const T& rhs)
{
return lhs < rhs ? lhs : rhs;
}
- 类型参数定义:通常使用单个大写字母,比如T
- 关键字:使用
typename
作为类型占位符 - 模板实例化(
template instantiation
):编译器从模板中生成类或函数的过程
类型参数¶
可同时定义多个类型参数
template <typename T, typename U, typename V> class Foo{};
关键字class也可作为类型占位符,其作用和typename
一样
template <class T, class U, class V> class Foo{};
使用椭圆运算符(...
)可以定义一个模板,其可以操作零个或多个类型参数
template<typename... Arguments> class vtclass;
vtclass< > vtinstance1;
vtclass<int> vtinstance2;
vtclass<float, bool> vtinstance3;
非类型参数¶
可以在模板中使用非类型参数,也称为值参数
template<typename T, size_t L>
class MyArray
{
T arr[L];
public:
MyArray() { ... }
};
模板作为模板参数¶
模板可以作为模板参数,示例如下:
template<typename T, template<typename U, int I> class Arr>
class MyClass
{
T t; //OK
Arr<T, 10> a;
U u; //Error. U not in scope
};
其中,能够在类MyClass
中使用模板参数T
和Arr
,不能使用U
和I
默认模板参数¶
可以在模板定义中设置默认参数,必须将默认参数放置在最后
template <class T, class Allocator = allocator<T>> class vector;
在使用过程中可以忽略默认参数位置
vector<int> myvector;
vector<int, MyAllocator> myvector;
如果所有模板参数都有默认值,那么可以不输入任何值,只使用空的尖括号
template<typename A = int, typename B = double>
class Bar
{
//...
};
...
int main()
{
Bar<> bar; // use all default type arguments
}
模板专门化¶
模板专门化:使用通用模板和一个或多个专用模板,专用模板指定特殊类型下的操作方式,其他类型使用通用模板完成
template <typename K, typename V>
class MyMap{/*...*/};
// partial specialization for string keys
template<typename V>
class MyMap<string, V> {/*...*/};
...
MyMap<int, MyClass> classes; // uses original template
MyMap<string, MyClass> classes2; // uses the partial specialization
- 完全专业化(
complete specialization
):指的是模板所有类型参数均被指定 - 部分专业化(
partial specialization
):指的是模板部分类型参数被指定