模板概述

参考:Templates (C++)

模板定义和使用

模板定义示例如下:

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中使用模板参数TArr,不能使用UI

默认模板参数

可以在模板定义中设置默认参数,必须将默认参数放置在最后

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):指的是模板部分类型参数被指定