目录
- 如何实现一个通用的交换函数呢?
-
- 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;
- }
- ......
使用函数重载虽然可以实现,但是有一下几个不好的地方:
重载的函数仅仅是类型不同,代码复用率比较低,只要有新类型出现时,就需要用户自己增加对应的函 数
代码的可维护性比较低,一个出错可能所有的重载均出错 那能否告诉编译器一个模子,让编译器根据不同的类型利用该模子来生成代码呢?
函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本。
函数模板格式:
template
用class也一样:
template
- template <class T>
- void Swap(T &x, T &y)
- {
- T tmp = x;
- x = y;
- y = tmp;
- }
-
- int main()
- {
- int a=1,b=2;
- Swap(a,b);
- cout<" "<
-
- double aa=1.1,bb=2.1;
- Swap(aa,bb);
- cout<
" "< -
-
- return 0;
- }
当然 虽然提供了模版,但在使用时,int型与double型调用的函数都是不同的
函数模板的原理:
函数模板是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具。所以其实模板就是将本来应该我们做的重复的事情交给了编译器
类型推演(实例化)
若在使用模版的同时,自己写出了有具体类型的相关函数,编译器会优先调用自己实现的函数:
- template <class T>
- void Swap(T &x, T &y)
- {
- T tmp = x;
- x = y;
- y = tmp;
- }
-
- void Swap(double &x, double &y)
- {
- double tmp = x;
- x = y;
- y = tmp;
- }
函数模板的实例化:
用不同类型的参数使用函数模板时,称为函数模板的实例化。模板参数实例化分为:隐式实例化和显式实例化。
1.隐式实例化:让编译器根据实参推演模板参数的实际类型:
- template <class T>
- T Add(const T &left, const T &right)
- {
- return left + right;
- }
- int main()
- {
- int a1 = 10, a2 = 20;
- double d1 = 10.0, d2 = 20.0;
- Add(a1, a2);
- Add(d1, d2);
- /*
- 该语句不能通过编译,因为在编译期间,当编译器看到该实例化时,需要推演其实参类型 通过实参a1将T推演为int,通过实参d1将T推演为double类型,但模板参数列表中只有一个T, 编译器无法确定此处到底该将T确定为int 或者 double类型而报错
- 注意:在模板中,编译器一般不会进行类型转换操作,因为一旦转化出问题,编译器就需要背黑锅
- Add(a1, d1);
- */
- // 此时有两种处理方式:1. 用户自己来强制转化 2. 使用显式实例化
- Add(a, (int)d);
- return 0;
- }
2.显式实例化:在函数名后的<>中指定模板参数的实际类型
- template <class Z>
- Z Add(const Z &left, const Z &right)
- {
- return left + right;
- }
-
- int main()
- {
- int a1 = 10, a2 = 20;
- double d1 = 10.1, d2 = 22.2;
- cout << Add(a1, a2) << endl;
- cout << Add<int>(a1, d2) << endl;
- cout << Add<double>(d1, a2) << endl;
- cout << Add(d1, d2) << endl;
-
- return 0;
- }
如果类型不匹配,编译器会尝试进行隐式类型转换,如果无法转换成功编译器将会报错。
类模版
类模板的定义格式:
- template<class T1, class T2, ..., class Tn>
- class 类模板名
- {
- // 类内成员定义
- };
- template <class T>
- class Stack
- {
- private:
- T *_a;
- size_t _top;
- size_t _capaicty;
-
- public:
- Stack(int capaicty = 4)
- {
- _a = new T[capaicty];
- _top = 0;
- _capaicty = capaicty;
- }
- ~Stack()
- {
- delete[] _a;
- _capaicty = _top = 0;
- }
- };
-
- int main()
- {
- //类只能 显示实例化
- Stack <int>st1;
- Stack <double>st2;
-
- return 0;
- }
-
相关阅读:
R语言将数据转化为DALEX包期望的格式、使用DALEX包的explain函数对多个h2o算法模型构建解释器进行解释分析、使用验证集数据构建模型解释器
力扣刷题学习SQL篇——1-3 选择(从不订购的客户——使用not in)
Java配置线程池
Day 36 贪心算法 part05 : 435. 无重叠区间 763.划分字母区间 56. 合并区间
Java宝典-抽象类和接口
https部署(nginx代理) keycloak ,js加载不出来的问题
视频加密的误解
我们来聊聊锁升级吧
【MySql】MySQL概述及其语法概述
关于KMP模式匹配的一些思考
-
原文地址:https://blog.csdn.net/2301_77649794/article/details/134471845