行业知识
C++:模板
C++:模板
- 函数模板
- 显式实例化
- 模板参数缺省
- 参数匹配规则
- 类模板
- 类名与类型
- 类成员的声明定义分离
- 非类型模板参数
- 模板特化
- 函数模板特化
- 类模板特化
- 全特化
- 偏特化
- 部分特化
- 限制���化
在讲解模板前,我提出一个问题:
()如何实现一个通用的swap交换函数?
也许你可以这样:
()void Swap(int& left, int& right){int temp = left;left = right;right = temp;}void Swap(double& left, double& right){double temp = left;left = right;right = temp;}void Swap(char& left, char& right){char temp = left;left = right;right = temp;}......把每种类型都进行重载,写出n多种交换函数。
但这很明显是一个费力不讨好的方法,不仅会让代码冗余重复,而且写出这样的代码,也会耗费精力。
那么有没有一种办法,我们给编译器一个模板,编译器自动生成函数?
C++就样提供了模板,而C++最重要的STL库,也就是起源于模板的。
模板分为函数模板与类模板,我们先通过函数模板来了解模板的大部分规则:
函数模板
功能:
函数模板代表了一个函数家族,在使用时被参数化,根据实参的类型生成特定类型的版本
也就是说,我们可以通过一个函数模板,让编译器生成一整个同类型的函数家族。
语法:
template
template
而被class和typename定义是模板参数,它可以被任意类型代替。如果你不能理解,我们不妨看看示例。
示例:
template T Add(T x, T y){return x + y;}int Add(int x, int y){return x + y;}这个函数是不是很熟悉了?
也就是说,T是可以被替换的类型,那么我们要如何确定这个T的类型?
编译器会根据调用函数时传入的参数,自动判断类型。
比如以下调用:
Add(1, 5);Add(3.0, 5.0);
对于Add(1, 5);,其两个参数都是int类型,那么此时模板就会生成一个int类型的Add函数。
对于Add(3.0, 5.0);,其两个参数都是double类型,此时模板就会生成一个double类型的Add函数。
以此类推,我们不论想要多少种类型,只需要传入参数,让编译器自动识别,而我们只需要写一个模板,就可以衍生出无数种函数,这就是模板的优势。
那么我们现在来实现一下一开始swap函数的模板:
template void Swap(T& left, T& right){T temp = left;left = right;right = temp;}不过要注意,模板只是一个蓝图,本身不是函数,当我们传入指定类型参数,其就会生成相应的函数。
显式实例化
再回到刚刚的Add函数模板。
template T Add(T x, T y){return x + y;}如果我们传入两个不同类型的参数怎么办?
比如这样:
int a = 5;double b = 3.0;Add(a, b);
请问这个模板是转化为double类型好呢,还是转化为int类型好呢?
对编译器来说,这就是一个大问题了,如果转化错误了,编译器就要背黑锅。所以遇到这种情况,编译器不会为我们做决定,而是报错,必须由程序员指明要用哪一种类型的模板。
比如使用强制类型转换:
int a = 5;double b = 3.0;Add(a, (int)b);Add((double)a, b);
上述代码,Add(a, (int)b);将b转化为了int,此时模板推演出int类型的函数;而Add((double)a, b);将a转化为了double类型,此时模板推演出double类型的参数。
此外,我们还可以使用显式实例化的方式:
显式实例化,就是在使用模板时,明确的告诉模板,要用什么类型。
语法:
函数名 (参数);
比如:
int a = 5;double b = 3.0;Add (a, b);Add (a, b);
Add (a, b);此代码就是推演出int类型的函数;而Add (a, b);就是推演出double类型的函数。
模板参数缺省
在设置模板参数时,可以设置缺省值,在显式实例化时,对于没有指明的模板参数,会被推演为缺省值。
看到以下模板:
template void func(T1 a){T2 b = 5;cout T2 b = 5;cout return x + y;}int func(int x, int y){return x + y;}// 类内成员定义};public:stack(size_t capacity = 10):_pData(new T[capacity]),_size(0),_capacity(capacity){}private:T* _pData;size_t _size;size_t _capacity;};public:stack(size_t capacity = 10):_pData(new int[capacity]),_size(0),_capacity(capacity){}~stack();//声明private:int* _pData;size_t _size;size_t _capacity;};stack::~stack(){//函数体}//函数体}//函数体}public:private:T _arr[N];};return x
上一篇:阿里云服务器怎么那么贵?