C++模版template(泛型编程)初阶

1. 函数模版

1.1 隐式实例化

我们来看下面四个函数,逻辑完全相同,唯一不同的是参数类型,但是逻辑相同能不能写成一个函数呢?

cpp 复制代码
void Swap(int& a, int& b) {
	int tmp = a;
	a = b;
	b = tmp;
}
void Swap(double& a, double& b) {
	double tmp = a;
	a = b;
	b = tmp;
}
void Swap(char& a, char& b) {
	char tmp = a;
	a = b;
	b = tmp;
}
void Swap(float& a, float& b) {
	float tmp = a;
	a = b;
	b = tmp;
}

这就要引入模版了,我们先自己写个模版

cpp 复制代码
template<typename T>
void Swap(T& a, T& b) {
	T tmp = a;
	a = b;
	b = tmp;
}
int main() {
	int a = 0,b=1;
	double c = 1.1, d = 2.2;
	Swap(a, b);
	Swap(c, d);
	return 0;
}

我们看到底层实现是函数重载,也就是说其实调用还是调用像之前我们写的那些函数,不过是编译器帮我们把活干了

模版的推演

库里已经写好了,不需要我们写,我们拿来用就可以了,不过是小写

1.2 显式实例化

上面的是隐式实例化,但有些时候如果只是隐式实例化还不够,举例如下

cpp 复制代码
template<typename T>
T Add(const T& a, const T& b) {
	return a + b;
}
int main() {
	int a = 0;
	double b = 1.1;
	cout << Add(a, (int)b) << endl;
	cout << Add((double)a, b) << endl;//我们可以考虑强转
	cout << Add<int>(a, b) << endl;
	cout << Add<double>(a, b) << endl;//也可以考虑显式实例化,在函数名后加上<参数类型名>
	return 0;
}

当然模版可以有多个参数类型

cpp 复制代码
template<typename T1,typename T2>
T1 Add(const T1& a, const T2& b) {
	return a + b;
}
int main() {
	int a = 0;
	double b = 1.1;
	Add<int, double>(a, b);//显示实例化的时候按顺序给类型就可以了
	return 0;
}

其实显示实例化主要用于以下不能隐式实例化的情况

cpp 复制代码
template<typename T>
T* Alloc(int n) {
	return T[n];
}
int main() {
	Alloc<int>(20);
	return 0;
}

2. 类的模版

类的模版和函数模版有些相似,

cpp 复制代码
template<class T>
class Stack {
public:
	Stack(int capacity = 3);
	void Push(T& x) {
		if (_size == _capacity) {
			T* tmp = (T*)realloc(_array, sizeof(T) * _capacity * 2);
			if (NULL == tmp) {
				perror("realloc fail");
				return;
			}
			_array = tmp;
		}
		_array[_size++] = x;
	}
	~Stack() {
		if (_array) {
			free(_array);
			_array = nullptr;
			_size = 0;
			_capacity = 0;
		}
	}
private:
	T* _array;
	int _size;
	int _capacity;
};

//但是类存在成员函数声明和定义分离的问题,注意没有模版的情况下,类名和类型名是一致的,但是有了模版,类名是Stack,类型名是Stack<T>,函数在类外定义的情况下,用的是类型名::,同时不要忘记template<typename T>
template<typename T>
Stack<T>::Stack(int capacity) {
	_array = new T[capacity];
	_size = 0;
	_capacity = capacity;
}

int main() {
	Stack<double> s1;
	Stack<int>* p1 = new Stack<int>;
	delete p1;
	
	return 0;
}
相关推荐
大鹏的NLP博客1 小时前
C++ 内存安全的未来:从 Safety Profiles 到 Safe C++
c++·内存安全
程序员zgh1 小时前
C++ erase() 函数用法
c语言·开发语言·c++·学习
All for pursuit.2 小时前
【并查集-2】399.除法求值
数据结构·c++·算法·leetcode
程序喵大人3 小时前
【C++入门】编译链接模型 - 05 ODR 为什么会让重复定义变成工程炸点
开发语言·c++·编译链接·odr
汉克老师4 小时前
CSP-S 2026 初赛试题解析(第一部分:选择题(8-15))精讲
c++·csp-s·小学生·学c++编程
_wyt0014 小时前
洛谷 P10112 [GESP202312 八级] 奖品分配 题解
c++·数学·gesp·八级
朝朝辞暮i4 小时前
C++ 第 33 课:事件循环——spin() 到底在干什么
开发语言·c++·算法
殷色玫瑰4 小时前
AVL树:从平衡因子到四种旋转的完整实现
c语言·数据结构·c++·算法·visualstudio
进化中的刀盾兽5 小时前
从零实现 C++ AI 大模型接入 SDK(九):LLMManager 统一模型管理与请求路由
c++
会周易的程序员5 小时前
STVM OSAL 层架构设计文档
c++·物联网·嵌入式·虚拟机·iot·软plc·iec61131