C++初阶----模板初阶

引言

什么是模板

模板是泛型编程的基础,泛型编程是以一种独立于任何特定类型的方式编写代码。 模板也是创建泛型类或者函数的蓝图。 如:库容器,迭代器和算法,都是泛型编程的例子

1. 泛型编程

首先,我们应该了解什么是泛型编程?

泛型编程就好比设计一个通用的模版,使绝大部分的场景都可以通用这个模板,来解决问题等。就好比在建筑设计中,我们都需要搭建许多不同的房屋(别墅,住宅楼,办公楼),而泛型编程就好比工程师设计的建筑图纸,有了图纸才可以在许多不同的地方来建造住宅楼,而建造出来的楼层,就是通过模板实例化出来的代码段

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

如下场景

cpp 复制代码
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;
}
//......

使用函数重载固然也可以解决同样的问题,但这样也会带来一些问题:

  1. 重载的函数仅仅是类型不同,当有新类型的出现,有需要重新设计重载函数
  2. 代码的可维护性低,一个出错可能所有重载都出错

2. 函数模板

2.1 概念:通过使用类型参数来实现一个函数家族,使用时被参数化,根据参数类型产生相应的函数类型模板

2.2 模板格式:

注意需要几个不同类型的参数就typename 几个参数模板, 关键字 "typename" 是标注当前为 数据类型 有时可能编译器会出现某个名字是变量还是类型会产生分歧

template<typename T,typename K,>

返回值类型 函数名 (参数列表 (T ,K)){}

cpp 复制代码
template<typename T>
void Swap( T& left, T& right)
{
 T temp = left;
 left = right;
 right = temp;
}//也可以用指针  T*

2.3 函数模板的原理

函数模板是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具。所以其实模板就是将本来应该我们做的重复的事情交给了编译器。

也就是说在没有套用模板的时候,编译器是不会运行这段代码的

2.4 函数模板的实例化

用不同类型的参数 使用函数模板 ,称为函数模板的实例化。而模板实例化分为:隐式实例化 和显式实例化

隐式实例化:

cpp 复制代码
template<class T> 
T add(const T& i,const T j)
{ 
	return i+j;
}

int main()
{
	int i = 5,j = 4;
	double b = 5.1, d = 6.2;
	add(i,j);
	add(b,d);
	return 0;
}

显式实例化

如上的add函数

cpp 复制代码
void test()
{
	 int a= 10;
	 double b= 2.1;
	 add<int>(a, b)  //b会强制类型转换为int
}

2.5 模板餐宿的匹配原则

  1. 一个非模板函数可以和一个同名的函数模板同时存在,而且该函数模板还可以被实例化为这个非模板函

数

cpp 复制代码
// 专门处理int的加法函数
int Add(int left, int right)
{
 return left + right;
}

template<class T> 
T add(const T& i,const T j)
{ 
	return i+j;
}

void test()
{
 Add(1, 2); // 与非模板函数匹配,编译器不需要特化
 Add<int>(1, 2); // 调用编译器特化的Add版本
}

在这种情况下会优先匹配有实例化的函数,当没有此类型的实例化函数才会调用模板

对于非模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用非模板函数而不会从该模板产生出一个实例。如果模板可以产生一个具有更好匹配的函数, 那么将选择模板

模板函数不允许自动类型转换,但普通函数可以进行自动类型转换

3. 类模板

3.1 类模板的定义,具体可参考vector的实现

cpp 复制代码
template<class T1, class T2, ..., class Tn>
class 类模板名
{
 // 类内成员定义
};

3.2 类模板的实例化

类模板实例化与函数模板实例化不同,类模板实例化需要在类模板名字后跟<>,然后将实例化的类型放在<>中即可,类模板名字不是真正的类,而实例化的结果才是真正的类

cpp 复制代码
// Vector类名,Vector<int>才是类型
Vector<int> s1;
Vector<double> s2;
相关推荐
2601_962106643 小时前
【Java Set综合实战】商品管理系统 + 图书收藏系统|Product、Book自定义类全套代码
java
科技苑4 小时前
C++ CAS与ABA问题详解,无锁编程的经典陷阱怎么解决?
c++·人工智能
RuoyiOffice4 小时前
SpringBoot+Vue3 凭证生命周期设计:审核、过账、冲销与反过账怎样保持账目一致
java·spring boot·事务·springboot3·财务系统·会计凭证·ruoyi office
2601_962106644 小时前
HashMap入门|工号-姓名键值存储、两种遍历方式、根据key/value查
java
czq_26867194874 小时前
Python打卡第46天
开发语言·python
杨凯凡5 小时前
Spring Framework 7 API 版本管理实战:请求头路由、兼容迁移与废弃策略
java·rest api·springframework·spring boot 4·api版本管理
T_Wizard5 小时前
同一个问题写了 4 遍:官方 SDK / HTTP / Spring AI / LangChain4j,到底该选哪个
java·ai编程
hai_android5 小时前
AudioTrack 深度解析:从原理到实战
android·java·kotlin
斯维赤6 小时前
限流、熔断、降级,你真的分得清吗?
java·后端·架构
Evand J7 小时前
【MATLAB例程介绍】(17)永磁同步电机(PMSM)基于自适应无迹卡尔曼滤波(AUKF)的电流噪声在线估计。测量噪声协方差自适应与转速估计对比仿真
开发语言·matlab·卡尔曼滤波·无迹卡尔曼滤波·pmsm·电机滤波