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参数类型
}
相关推荐
小羊在奋斗2 分钟前
【C++】探秘二叉搜索树
c++·人工智能·神经网络·机器学习
白葵新21 分钟前
PCL addLine可视化K近邻
c++·人工智能·算法·计算机视觉·3d
MustardJim44 分钟前
Visual Studio 引入外部静态库与动态库
c++·visual studio
挽月0011 小时前
C++单例模式
开发语言·c++·单例模式
机器视觉知识推荐、就业指导1 小时前
Qt/C++ TCP调试助手V1.1 新增图像传输与接收功能(附发布版下载链接)
c++·qt·tcp/ip
wx200411021 小时前
Codeforces Round 973 (Div. 2) - D题
数据结构·c++·算法
DieSnowK2 小时前
[项目][WebServer][CGI机制 && 设计]详细讲解
linux·开发语言·c++·http·项目·webserver·cgi机制
归寻太乙2 小时前
C++函数重载完成日期类相关计算
开发语言·c++
尽蝶叙2 小时前
C++:分苹果【排列组合】
开发语言·c++·算法
憧憬成为原神糕手3 小时前
c++_list
开发语言·c++