> 技术文档 > C++模板

C++模板

模板 是 泛型编程的基础

泛型编程:编写与类型无关的通用代码,是代码复用的一种手段

函数模板

函数模板在使用时才会被参数、实例化,根据实参类型生成函数的特定版本

template// templatesize_t multi(const T& a, const T& b){return a * b;}

class & typename

在模板声明形参 T 时,class T 或者 typename T 是完全等价的,但如果有下面情况,必须用 typename

template// templatevoid print_list(const list& lt){typename list::const_iterator it = lt.begin();......}

这是在 模板函数 print_list 中,包括了 模板类 list :

const_iterator 是一个内嵌类型,即 嵌套在模板类 list 中的内置类型;

编译器在实例化 list 之前,不清楚 const_iterator 到底是一个内嵌类型,还是一个静态成员变量;

因为静态成员变量也有同样的突破类域的访问方式:类名::成员名 ,其实不仅静态成员变量,静态成员函数也是这样的访问方式;

所以回归问题,我们必须 使用typename 告诉编译器 const_iterator 是一个内嵌类型,等 list 实例化之后,去实例化的类里面找。

模板 & 同名函数

templatesize_t multi(const T& a, const T& b){return a * b;}int multi(const int& left, const int& right){return left * right;}

函数模板与同名函数同时存在,调用时,编译器能先调同名函数就会先调同名函数;

如果想指定调模板,那么需要显式实例化:

int a = 1, b = 2;multi(a, b); // 函数模板的显式实例化

显式实例化

除了上面提到 如果想指定调用函数模板需要显式实例化参数类型之外,还有一种情况:

templateT& func(int n){return new T[n];}func(10); // 必须显式实例化

调用这个模板函数时,编译器无法通过你传入的参数来推理出 模板参数 T 是什么类型,所以必须显式实例化。

类模板

类模板必须显式实例化:

templateclass A{public:A():_a(0),_b(nullptr){}private:T _a;T* _b;};A a; // 类模板的显式实例化

这个类的类名是 A , 类型是  A 

类模板的使用 参考函数模板。