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;
相关推荐
董先生_ad986ad1 小时前
C# 中的 `lock` 关键字本质
开发语言·c#
Lxinccode1 小时前
Java查询数据库表信息导出Word-获取数据库实现[1]:KingbaseES
java·数据库·word·获取数据库信息·获取kingbasees信息
元亓亓亓2 小时前
Java后端开发day36--源码解析:HashMap
java·开发语言·数据结构
sd21315122 小时前
RabbitMQ 复习总结
java·rabbitmq
道剑剑非道2 小时前
QT 打包安装程序【windeployqt.exe】报错c000007d原因:Conda巨坑
开发语言·qt·conda
小邓儿◑.◑2 小时前
C++武功秘籍 | 入门知识点
开发语言·c++
码银4 小时前
Java 集合:泛型、Set 集合及其实现类详解
java·开发语言
大G哥4 小时前
PHP标签+注释+html混写+变量
android·开发语言·前端·html·php
东阳马生架构4 小时前
Nacos简介—4.Nacos架构和原理
java
傻啦嘿哟4 小时前
HTTP代理基础:网络新手的入门指南
开发语言·php