C++ || 模板初阶 | 函数模板 | 类模板

泛型编程

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

  • 可以理解为活字印刷术类似的方式。

函数模板

函数模板概念

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

解决函数作用相同,但是参数类型不同,得写好几个参数不同但函数功能相同的代码,函数模板就是解决这个问题。

本来应该我们做的重复的事情交给了编译器。

函数模板语法

cpp 复制代码
template<typename T1,typename T2,...,typename Tn>
返回类型 函数名(参数列表){}
  • typename是定义模板参数关键字
  • 可以使用class,但不能是struct

函数模板使用案例

cpp 复制代码
#include <stdio.h>
#include <iostream>
using namespace std;
//template<typename T>
template<class T>
//typename是定义模板参数的关键字,
//也可以使用class,但不能是struct
void Swap(T& left, T& right)
{
	T temp = left;
	left = right;
	right = temp;
}
int main()
{
	int a = 3, b = 5;
	Swap(a, b);
	cout << "a=" << a << " " << "b=" << b << endl;//a=5 b=3
	double d = 2.63, e = 9.35;
	Swap(d, e);
	cout << "d=" << d << " " << "e=" << e << endl;//d=9.35 e=2.63
	return 0;
}

函数模板原理

  • 函数模板,本身并不是函数;
  • 编译器产生特定具体类型函数的模具;
  • 在编译器编译阶段,编译器 根据传入的实参类型推演生成对应类型的函数
  • 例如:当用double类型使用函数模板时,编译器通过对实参类型的推演,将T确定为double类型,然后产生一份专门处理double类型的代码。

函数模板实例化

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

隐式实例化

隐式实例化 ,让编译器自己根据实参推演模板参数的实际类型。

cpp 复制代码
template <typename T>
T Add(const T& left, const T& right)
{
	return left + right;
}
int main()
{
	int a1 = 10, a2 = 20;
	double d1 = 10.9, d2 = 45.8;
           //隐式实例化
	cout << Add(a1, a2) << endl; //30
	cout << Add(d1, d2) << endl;//56.7

	// Add(a1, d1) 会报错 
	// 编译器无法确定此处到底该是将T确定为int还是double
	// 两种处理方式:①用户强转 Add(a1, (int)d1) ;②显示实例化 Add<int>(a1, d1) 
	//cout << Add(a1, d1) << endl;//56.7
	cout << Add(a1, (int)d1) << endl;//56.7
	return 0;
}

显示实例化

显示实例化 ,在函数名后的**<>中指定** 模板参数的实际类型

cpp 复制代码
template <typename T>
T Add(const T& left, const T& right)
{
	return left + right;
}
int main()
{
	int a = 10;
	double d = 10.9;
	        //显示实例化
	cout << Add<int>(a, d) << endl;//20
	return 0;
}

模板参数的匹配规则

  • 一个非模板函数可以和一个同名模板函数同时存在。

非模板函数与同名模板函数同时存在时:

  • 调用函数与非模板函数匹配时,编译器不需要推演特化;
  • 有显示实例化,编译器进行函数模板推演;
  • 优先调用非模板函数;
  • 模板函数不允许自动类型转换,但普通函数可以进行自动类型转化。

类模板

将类中的成员变量或者成员函数的参数数据类型进行模板化。

类模板名字不是真正的类,实例化的结果才是真正的类。

类模板语法

  • 类模板中函数放在类外进行定义时,需要加模板参数列表。
cpp 复制代码
template<class T1,class T2,...,class Tn>
class 类模板名
{
	//类成员
};

//类模板函数在类外定义,加模板参数列表
template<class T1,class T2,...,class Tn>
类模板名<T1/T2/.../Tn>::类模板成员函数名()
{
    函数功能
}

int main()
{
    类模板名<实例化类型> 类对象实例化名字;//Date d;
}

类模板实例化

cpp 复制代码
类模板名<实例化的类型> 实例化类对象名;
//Date d1;

类模板名字不是真正的类,实例化的结果才是真正的类。

类模板使用案例

cpp 复制代码
template<class T>
class Vector
{
private:
	T* _pData;
	size_t _size;
	size_t _capacity;

public:
	Vector(size_t capacity = 10)
		:_pData(new T[capacity])
		,_size(0)
		,_capacity(capacity)
	{

	}

	~Vector();
};

template <class T>
Vector<T>::~Vector()
{
	if (_pData)
		delete[] _pData;
	_size = 0;
	_capacity = 0;
}

int main()
{
	Vector<int> S1;
	//Vector类名 int参数类型
}
相关推荐
车载小杜1 小时前
基于指针的线程池
开发语言·c++
云 无 心 以 出 岫3 小时前
贪心算法QwQ
数据结构·c++·算法·贪心算法
换一颗红豆4 小时前
【C++ 多态】—— 礼器九鼎,釉下乾坤,多态中的 “风水寻龙诀“
c++
随便昵称4 小时前
蓝桥杯专项复习——前缀和和差分
c++·算法·前缀和·蓝桥杯
commonbelive4 小时前
团体程序设计天梯赛——L1-100 四项全能
c++
genispan4 小时前
QT/C++ 多线程并发下载实践
开发语言·c++·qt
小卡皮巴拉5 小时前
【力扣刷题实战】矩阵区域和
开发语言·c++·算法·leetcode·前缀和·矩阵
Pacify_The_North5 小时前
【C++进阶三】vector深度剖析(迭代器失效和深浅拷贝)
开发语言·c++·windows·visualstudio
神里流~霜灭5 小时前
蓝桥备赛指南(12)· 省赛(构造or枚举)
c语言·数据结构·c++·算法·枚举·蓝桥·构造
扫地的小何尚5 小时前
NVIDIA工业设施数字孪生中的机器人模拟
android·java·c++·链表·语言模型·机器人·gpu