当前位置: 首页 > news >正文

C++:template(函数模板)

基础使用

在使用函数的过程中可能会遇到同一个函数名被多次调用的情况,比如

#include <iostream>using namespace std;void Swap(int &i1,int &i2){int tmp;tmp = i1;i1 = i2;i2 = tmp;cout <<"交换后的整形1="<<i1<<"交换后的整形2="<<i2<<endl;
}
void Swap(double &d1,double &d2){double tmp;tmp = d1;d1 = d2;d2 = tmp;cout <<"交换后的浮点形1="<<d1<<"交换后的浮点形2="<<d2<<endl;
}
void Swap(string &s1,string &s2){string tmp;tmp = s1;s1 = s2;s2 = tmp;cout <<"交换后的字符串1="<<s1<<"交换后的字符串2="<<s2<<endl;
}
int main(){int a1 = 3, a2 = 4;double d1 = 3.5, d2 = 4.5;string s1 = "绿茶", s2 = "清补凉";Swap(a1,a2);Swap(d1,d2);Swap(s1,s2);
}

输出结果

交换后的整形1=4交换后的整形2=3
交换后的浮点形1=4.5交换后的浮点形2=3.5
交换后的字符串1=清补凉交换后的字符串2=绿茶

这样定义多个函数虽然也能实现想要的效果,但使用函数模板更加方便 

#include <iostream>using namespace std;template<typename T>
void Swap(T &t1,T &t2){T tmp;tmp = t1;t1 = t2;t2 = tmp;cout <<"交换后的整形/浮点形/字符串1="<<t1<<"交换后的整形/浮点形/字符串2="<<t2<<endl;
}
int main(){int a1 = 3, a2 = 4;double d1 = 3.5, d2 = 4.5;string s1 = "绿茶", s2 = "清补凉";Swap(a1,a2);Swap(d1,d2);Swap(s1,s2);
}

输出结果

交换后的整形/浮点形/字符串1=4交换后的整形/浮点形/字符串2=3
交换后的整形/浮点形/字符串1=4.5交换后的整形/浮点形/字符串2=3.5
交换后的整形/浮点形/字符串1=清补凉交换后的整形/浮点形/字符串2=绿茶

 这样大大节约了写代码的时间

假如传进去的数据类型不一样,则定义的函数模版需要两个typename

#include <iostream>using namespace std;template<typename T1, typename T2>
void Swap(T1 &t1,T2 &t2){cout <<t1<<"的价格是"  << t2 << endl;
}
int main(){int a1 = 3, a2 = 4;double d1 = 3.5, d2 = 4.5;string s1 = "绿茶", s2 = "清补凉";Swap(s1,a1);Swap(s2,a2);
}

函数模板还能为函数指定返回值,但要注意返回值要相同

#include <iostream>using namespace std;template<typename T1, typename T2>
T1 Swap(T1& t1, T2& t2) {cout << t1 << "的价格是" << t2 << endl;return t1;
}
int main(){int a1 = 3, a2 = 4;double d1 = 3.5, d2 = 4.5;string s1 = "绿茶", s2 = "清补凉";string ss1 = Swap(s1,a1);string ss2 = Swap(s2,a2);cout << ss1 << ss2 << endl;
}

输出结果

 绿茶的价格是3
清补凉的价格是4
绿茶清补凉

 函数模板的具体化

定义:可以提供一个具体化的函数定义,当编译器找到与函数调用匹配的具体化定义时,将使用该定义,不再寻找模板

 假如传入类的对象可以这么写

#include <iostream>using namespace std;
class C {
public:string s;C(const string& ss) :s(ss) {}
};template<typename T1, typename T2>void Swap(T1& t1, T2& t2) {string c3 = t1.s;t1.s = t2.s;t2.s = c3;
}
int main(){C c1("绿茶");C c2("清补凉");cout << "交换前c1是" << c1.s << "c2是" << c2.s << endl;Swap(c1,c2);cout << "交换后c1是" << c1.s << "c2是" << c2.s << endl;
}

 输出结果

交换前c1是绿茶c2是清补凉
交换后c1是清补凉c2是绿茶

但是当Swap要实现既能传入string也能传入类的对象时,需要具体化函数模板 

 

#include <iostream>using namespace std;
class C {
public:string s;C(const string& ss) :s(ss) {}
};template<typename T1, typename T2>
void Swap(T1& t1, T2& t2) {string tmp = t1;t1 = t2;t2 = tmp;
}
template<>
void Swap<C>(C& t1, C& t2)//用尖括号指定的数据类型,不加其实也可以 
{
string c3 = t1.s;
t1.s = t2.s;
t2.s = c3;
}
int main() {C c1("绿茶");C c2("清补凉");string s1 = "绿茶";string s2 = "清补凉";cout << "交换前c1是" << c1.s << "c2是" << c2.s << endl;cout << "交换前s1是" << c1.s << "s2是" << c2.s << endl;Swap(c1, c2);Swap(s1, s2);cout << "交换后c1是" << c1.s << "c2是" << c2.s << endl;cout << "交换后s1是" << c1.s << "s2是" << c2.s << endl;
}

 输出结果

交换前c1是绿茶c2是清补凉
交换前s1是绿茶s2是清补凉
交换后c1是清补凉c2是绿茶
交换后s1是清补凉s2是绿茶

分文件编写

普通函数和函数模板的具体化版本在头文件中声明,在源文件中定义,创建函数模版的声明和定义都在头文件中,否则会运行出错

注意

1、虚函数不能用,析构函数也不能用

2 、使用函数模板不会发生隐式转换,除了显式指定函数模板的数据类型时会

3、可以重载

4、数据类型必须对应

5、优先级:具体函数>函数模板具象化>函数模板,如果在定义函数的同时还想使用函数模板或者具体化的函数模板可以<>,比如Swap<>(a,b);

6、如果函数模板的参数更加匹配,将优先使用

http://www.xdnf.cn/news/393301.html

相关文章:

  • GitLab搭建与使用(SSH和Docker)两种方式
  • [学习]RTKLib详解:convkml.c、convrnx.c与geoid.c
  • HTTP 错误状态码以及常用解决方案
  • C++进阶--使用红黑树封装map和set
  • 原型链与继承机制:继承背后的秘密
  • Baklib内容中台的核心架构是什么?
  • 蓝桥杯14届国赛 班级活动
  • 反向代理对于 网络安全中服务器的一些思考
  • MiniMind:3块钱成本 + 2小时!训练自己的0.02B的大模型。minimind源码解读、MOE架构
  • JS | 正则 · 常用正则表达式速查表
  • Go语言——kratos微服务框架使用
  • Google语法整理
  • 《软件项目管理》笔记二
  • 从 TTS 到 TTRL:无标签数据强化学习探索与展望
  • CMOS内存的地址空间在主内存空间中吗?
  • Java Solon-MCP 实现 MCP 实践全解析:SSE 与 STDIO 通信模式详解
  • 深入剖析卷积神经网络之卷积层:原理、类型与优化策略
  • Baklib内容管理平台的核心组成是什么?
  • SpringBoot 自动装配原理 自定义一个 starter
  • Android架构模式推荐及分析和MVC架构模式制作一个简单的底部tab切换
  • 嵌入式学习笔记 - STM32 ADC,多重转换,内部参考电压,
  • linux基础操作4------(权限管理)
  • 产业带数据采集方案:1688 API 接口开发与实时数据解析实践
  • 【人工智能】 大模型训练的艺术:从数据到智能的飞跃
  • 【RP2350】香瓜树莓派RP2350之Delay延时
  • 基于SpringBoot的在线教育管理系统
  • spring
  • Python工具链UV整合环境管理
  • 国内外主流AI编程工具全方位对比分析(截至2025年5月)
  • SpringCloud Gateway知识点整理和全局过滤器实现