简单模板笔记

引入

在C语言中完成两数交换,如果每次交换的类型不同,我们需要写多个函数就和下面一样。C语言中得保证函数名字的不同来保证函数之间不会冲突。在C++中就有函数重载和模板了。

cpp 复制代码
#include <stdio.h>
void Swap1(int* a, int* b)
{
	int tmp = *a;
	*a = *b;
	*b = tmp;
}
void Swap2(float* a, float* b)
{
	float tmp = *a;
	*a = *b;
	*b = tmp;
}
int main()
{
	float a1 = 2.2, a2 = 1.1;
	Swap2(&a1, &a2);
	return 0;
}

C++中的函数重载

C++中摒弃了C语言中函数名不可以相同的特性,因为就像swap函数,他是交换函数,让这一个函数名完成多种类型变量的交换多舒服,所以C++中让参数的不同来判断不同的函数,相同的函数名和不同的参数就构成了函数重载(函数的返回值不可以作为不同函数的区分点)

这样写很多个相同的函数也是很麻烦的,这时候C++就引出了模板,直接简化了。

cpp 复制代码
#include <iostream>
using namespace std;

void Swap(int& a, int& b)
{
	int tmp = a;
	a = b;
	b = tmp;
}

void Swap(float& a, float& b)
{
	float tmp = a;
	a = b;
	b = tmp;
}

void Swap(double& a, double& b)
{
	double tmp = a;
	a = b;
	b = tmp;
}


int main()
{
	double a = 1.1, b = 2.2;
	Swap(a, b);
	int a1 = 1, b1 = 2;
	Swap(a1, b1);
	float a2 = 3.3, b2 = 4.4;
	Swap(a2, b2);
	return 0;
}

函数模板

函数模板的概念:函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参的类型产生特定的类型。

1.typename是用来定义模板参数关键字,也可以使用class(不可以使用struct)

cpp 复制代码
#include <iostream>
using namespace std;

//template<typename T1, typename T2,...,tepename Tn>
//返回值类型 函数名(参数列表)
template<typename T>
void Swap(T& a, T& b)
{
	T temp = a;
	a = b;
	b = temp;
}


int mian()
{
	int a = 2, b = 1;
	Swap(a, b);
	return 0;
}

函数模板的实例化

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

1.隐式实例化:让编译器根据实参推导模板参数的类型

cpp 复制代码
#include <iostream>
using namespace std;

template<typename T>
T Add(T& a, T& b)
{
	return a + b;
}


int main()
{

	int a1 = 1, a2 = 2;
	double b1 = 1.1, b2 = 2.2;
	Add(a1, a2);
	Add(b1, b2);
	//下面这里是不可以的,第一个参数是int第二个参数是double,
	// 一共就一个模板T,这个到底是int还是double是不明确的
	// 所以我们可以强制类型转化/或者是显式实例化
	//Add(a1, b1);
	Add(a1,(int&)b1)
	return 0;
}

2.显式实例化:在函数名的后面的<>中指定模板参数的类型

cpp 复制代码
#include <iostream>
using namespace std;

template<typename T>
T Add(T& a, T& b)
{
	return a + b;
}

int main()
{

	int a1 = 1, a2 = 2;
	double b1 = 1.1, b2 = 2.2;
	Add(a1, a2);
	Add(b1, b2);
	//下面这里是不可以的,第一个参数是int第二个参数是double,
	// 一共就一个模板T,这个到底是int还是double是不明确的
	// 所以我们可以强制类型转化/或者是显式实例化
	//Add(a1, b1);
	Add(a1,(int&)b1);

	int a = 10;
	double b = 20.0;
///////////////////////
	Add<double>(b1, b);
	return 0;
}

模板函数的匹配

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

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

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

cpp 复制代码
#include <iostream>
using namespace std;
//专门处理int
int Add(int a, int b)
{
	return a + b;
}
//通用
template<typename T>
T Add(T a, T b)
{
	return a + b;
}

int main()
{
	Add(1, 2);//调用第一个int类型的函数
	Add<int>(1, 2);//调用T类型的函数
	Add(1, 2.0);//模板函数可以生成更好的
	return 0;
}

类模板

类模板的定义

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

例如

cpp 复制代码
#include <iostream>
using namespace std;
//模板和声明不建议分离到两个文件.h和.cpp会导致链接错误
template<class T>
class A
{
public:
	A(int a = 0)
		:_a(a)
	{}
private:
	T _a;
};
int main()
{
	return 0;
}

模板的实例化

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

cpp 复制代码
//A是类名,A<int>才是类型
A<int> s1;    // int
A<double> s2; // double
相关推荐
码完就睡9 分钟前
数据结构——红黑树
数据结构
码爸17 分钟前
数据结构详细介绍
数据结构
qq_2842740524 分钟前
数控铣床与加工中心笔记:铣刀与刀柄系统、G54试切对刀、镜像加工指令、孔加工工艺(钻扩铰镗)与固定循环G73/G83/G81/G76/G87/G84
笔记·学习·自动化·制造
Navigator_Z28 分钟前
LeetCode //C - 1286. Iterator for Combination
c语言·算法·leetcode
北极有牛1 小时前
cpp学习笔记--常量指针
java·开发语言·算法
GPU实战笔记1 小时前
云端 GPU 训练的账户余额提醒:它能说明什么,不能说明什么?
深度学习·算法·成本管理·gpu云计算·云端训练
Titan20241 小时前
MySQL访问个人学习笔记
笔记·学习·mysql
浮链序1 小时前
怎么证明"你这个模型是偷我的"——把蒸馏变成取证工具
算法·安全·llm
小O的算法实验室1 小时前
IEEE TMC,面向异构物联网的多目标量子行为拓扑优化算法
算法
liliangcsdn2 小时前
派息率指标的应用探索和分析
大数据·算法