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

C++ 泛型编程详解

泛型编程与面向对象编程的目标相同,即使重用代码和抽象通用概念的技术更加简单。但是面向对象编程强调编程的数据方面,泛型编程强调的是独立于特定数据类型。

这一篇介绍一下 C++ 编程中与面向对象并列的另一大分支——泛型编程,这一篇主要介绍函数模板、类模板和成员模板三大部分

如有侵权,请联系删除,如有错误,欢迎大家指正,谢谢

泛型编程

模板是泛型编程的一种重要思想,STL(Standard Template Library,标准模板库)是采用模板实现的一个实例
函数模板

对比函数重载(同一作用域内函数名相同,参数列表不同的函数),函数模板只需要一个函数就实现了函数重载的部分功能(参数个数相同类型不同,函数重载需要定义多个同名参数列表不同的函数)

1

2

3

4

5

6

7

8

9

template<typenameT,typenameY>// 这也可以写 template<class T, class Y> 此处的 class 和 typename 作用相同

voidtfunc(T& t, Y& y) {

cout << t <<" "<< y << endl;

}

intn = 2;

doubled = 2.1;

tfunc(n, d);

// 运行结果:2 2.1

函数模板具体化,函数模板具体化就是将某一(某几)个要处理的类型单独处理,需要单独写一个实现,形式是 template<> void fun(type& t);,函数模板的具体化和普通函数可以同时存在,调用顺序是 普通函数 > 函数模板具体化 > 模板函数

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

// ====== 测试一:函数模板针对特殊数据类型具体化 ======

structNode {

intval;

Node* next;

};

// 函数模板

template<typenameT>

voidtfunc(constT& t) {

cout <<"template: "<< t << endl;

}

// 函数模板具体化(用于处理Node类型数据)

template<>

voidtfunc<Node>(constNode& node) {

cout <<"template<Node>: "<< node.val << endl;

}

// 函数模板具体化(用于处理int类型数据)

template<>

voidtfunc<int>(constint& n) {

cout <<"template<int>: "<< n << endl;

}

// 普通函数

voidtfunc(constint& n) {

cout <<"tfunc(): "<< n << endl;

}

doubled = 2.1;

tfunc(d);// 函数模板未具体化double类型函数,调用模板

Node node{ 2, nullptr };

tfunc(node);// 函数模板具体化Node类型函数,调用函数模板的具体化

intn = 2;

tfunc(n);// 函数模板具体化int类型函数,也存在普通函数,调用普通函数

// ====== 测试二:函数模板部分具体化 ======

template<typenameT1,typenameT2>

voidtfunc(T1 t1, T2 t2) {

cout <<typeid(T1).name() <<" and "<<typeid(T2).name() <<": "<< t1 <<" "<< t2 << endl;

}

template<typenameT1>

voidtfunc(T1 t1,inti) {

cout <<typeid(T1).name() <<" and "<<"int: "<< t1 <<" "<< i << endl;

}

template<typenameT2>

voidtfunc(longl, T2 t2) {

cout <<"long and "<<typeid(T2).name() <<": "<< l <<" "<< t2 << endl;

}

template<>

voidtfunc(shortl,inti) {

cout <<"long and int: "<< l <<" "<< i << endl;

}

// 分别调用以上四个模板函数

tfunc(char('c'),char('c'));

tfunc(char('c'),int(10));

tfunc(long(10),char('c'));

tfunc(short(10),int(10));

函数模板实例化,让编译器生成指定类型的函数定义,不用写函数的实现,形式是 template void fun(type& t);

1

2

3

4

5

6

7

8

// 函数模板

template<typenameT>

voidtfunc(constT& t) {

cout <<"template: "<< t << endl;

}

// 函数模板实例化,不用写函数的实现,编译器会生成该类型的模板具体化函数

templatevoidtfunc<char>(constchar& c);

类模板

类模板可以指定默认模板参数(函数模板不可以),跟函数参数的默认值一样,必须从右向左连续赋值默认类型,如果实例化对象时又传递了类型,默认类型会被覆盖掉,跟函数参数是一样的
创建对象时需要传递模板参数列表,模板参数列表加在类名后面 ClassName< typename T > classN; 如果类的模板参数列

表有默认值,可以不传模板参数,但一定要加 <> 如 ClassName< > classN; 创建堆区对象的时候,所有的类名称后面都要加模板参数列表,如 ClassName< typename T >* classN = new ClassName< typename T>; 除了类内,其他地方出现 ClassName 的地方一般都要加模板参数列表

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

template<typenameT =int,typenameY =char>// 此处指定了模板默认参数,部分指定必须从右到左指定

classTest {

public:

Test(T t, Y y) : t(t), y(y) {

}

voidtfunc();

private:

T t;

Y y;

};

template<typenameT,typenameY>// 类模板的函数在类外实现,需要加上模板参数列表,但不需要加指定的默认模板参数

voidTest<T, Y>::tfunc() {// 类外使用Test需要加模板参数

cout << t <<" "<< y << endl;

}

intn = 2;

doubled = 2.1;

Test<int,double> test(n, d);// 此处如果使用默认模板参数可定义为 Test<> test(int(2), char('a'));

test.tfunc();

// 运行结果:2 2.1

类模板的继承,类模板被继承后参数的传递方式主要有两种,一种是直接在子类继承父类的时候,为父类指定固定的类型,二是通过子类模板参数列表传递

http://www.cnnetsun.cn/news/2612371.html

相关文章:

  • YOLOv8n-Ghost优化与FPGA加速在SAR船舶检测中的应用
  • 爱搜索 GEO 营销系统全维度实测与价值评估
  • Buck电路纹波太大?可能是你的电容选错了!深入剖析ESR和容值对纹波的实际影响
  • GenUIKit:基于类型安全的UI-Shaped JSON构建可靠AI驱动前端界面
  • Potsdam数据集切割参数怎么调?聊聊SIZE和OVERLAP对模型训练的实际影响
  • 如何高效获取Zenodo科研数据:专业开发者的完整解决方案
  • 移动端GPU内存告急?手把手教你为Unity/UE4手游项目选对纹理压缩格式(ASTC vs ETC2实战解析)
  • 基于多智能体流水线的代码审查自动化实践与架构解析
  • 边缘-云端协作的Verilog代码优化框架解析
  • Windows 10/11下OpenCV抓取USB摄像头黑屏/报错?可能是MSMF后端在搞鬼
  • 保姆级教程:解决Ubuntu 20.04下U-Boot无法NFS挂载的TTT与cannot mount错误
  • Claude vs GPT vs Gemini:面向工程工作流的系统级AI编码助手评测
  • 多端口酒馆经营系统点餐游戏拼桌全场景解决方案
  • 多语言大模型评估:从基准测试到推理语言分析,如何衡量真实跨语言能力
  • 别再手动找洞了!Open Cascade 7.7.0 一键提取面内所有孔洞(内环线)的实战代码
  • 同一批任务,我算了一下用不同模型 API 的实际花费,差距有点出乎意料(2026 多模型成本建模)
  • Keil C51带符号位域问题解析与解决方案
  • MARVEL框架:RISC-V ISA扩展优化CNN边缘计算
  • 50.黑砖救砖终极方案!高通 EDL + 联发科 BROM + 苹果 DFU 实操教程
  • Java HashMap 与 ConcurrentHashMap 核心原理总结:从 Hash 冲突到 LongAdder
  • Apifox 性能测试
  • AMBA总线中解锁事务与独占访问的机制解析
  • 深入NVIDIA Container Runtime Hook:它是如何‘劫持’Docker容器启动流程,为你注入GPU能力的?
  • 仅限首批内测团队开放:ChatGPT餐厅推荐生成工业级模板库(含21个行业定制Prompt+5类隐私脱敏策略)
  • 1.OpenClaw_构建你的第一个Agent
  • 知识图谱:为AI助手构建关系型上下文,解决复杂决策难题
  • 超越first-fit:从ucore Lab 2出发,聊聊伙伴系统(Buddy System)与SLUB分配器的设计与实现思路
  • 从Pure-FTPd配置项入手,打造一个安全又高效的内部文件共享服务器
  • 避坑指南:在华为云CCE上手动部署Nacos集群,我踩过的那些‘服务发现’的坑
  • 在PyTorch中给ASPP模块加上SENet注意力,提升语义分割模型性能(附完整代码)