C++ - 模板(一) #泛型编程 #函数模板 #类模板

C#模板匹配创建模板与查找模板函数 class ShapeModulInspect { /// <summary> /// /// </summary> /// <param name="InspectImg">图像</param> /// <param name="ModulRoi">ROI</param> /// <param name="AngleStar 阅读详情

文章目录

前言

一、泛型编程

二、函数模板

1、函数模板的概念

2、函数模板的格式

3、函数模板的原理

4、函数模板的实例化

1、隐式实例化:

2、显式实例化:

5、模板参数的匹配原则

三、类模板

1、类模板的定义格式

2、类模板的实例化

总结


前言

路漫漫其修远兮,吾将上下而求索;


一、泛型编程

何为泛型编程?

  • 针对广泛的类型去写代码;即编写与类型无关的通用代码,是代码复用的一种手段;

Q:如何实现一个通用的交换函数呢?

代码如下:

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、代码的可维护性比较低,一个出错可能所有的重载均会出错;

那么此时我们就会想,能否直接给编译器一个“模板”,然后编译器会通过不同的类型利用该“模板”生成函数呢;就像做月饼一样,我们可以用月饼模具做出许多不同馅料的月饼出来;

于是乎,C++就提供了一种机制:模板;

模板是泛型编程的基础;

二、函数模板

1、函数模板的概念

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

2、函数模板的格式

template<typename T1,typename T2,......,typename Tn>

返回类型   函数名(参数列表){} 

新增加了两个关键字:template (模板)、 typename(类型名称);

注意: typename 是用来定义模板参数关键字,也可以使用class(切记:不能用struct 来代替class);即函数模板的格式还可以这么写:

template<classT1,classT2,......,classTn>

返回类型   函数名(参数列表){} 

将上面用函数重载实现的交换的代码写成函数模板,代码如下:

template<typename T>
void Swap(T& left, T& right)
{
	T temp = left;
	left = right;
	right = temp;
}

注:模板参数可以类比我们之前学习的函数参数;

  • 对于模板参数来说,<> 中定义的是类型,如果有多个类型,其间需要用 , 进行分隔;模板参数:关键字template<typename 类型名称,...>
  • 而对于函数参数,() 中定义的是参数对象、参数变量;可能会有多个参数,参数之间用 , 进行分隔。函数参数: 函数返回值类型 函数名(类型 变量名, ... )

使用该函数模板,代码如下:

//函数模板 --> 泛型
template<typename T>
void Swap(T& left, T& right)
{
	T temp = left;
	left = right;
	right = temp;
}

int main()
{
	int x = 1, y = 2;
	Swap(x, y);
	cout << "x:" << x << " " << "y:" << y << endl;

	double m = 1.1, n = 2.2;
	Swap(m, n);
	cout << "m:" << m << " " << "n:" << n << endl;

	return 0;
}

运行结果如下:

Q:模板的原理是什么?“模具”

调用的是编译器根据这个模板参数的匹配取去推演出生成T为int、double的Swap 函数(这是两个函数);也就是意味着,写成了模板,将工作交给了编译器,便利了我们去写代码;此处的底层实际上还是两个函数;

我们可以观察一下反汇编:

模板相当于是活字印刷的模具,而干活的人是编译器;模板的原理:给一个模板,编译器帮你去生成对应的函数;

3、函数模板的原理

编译器根据模板来生成对应的函数:

  • 步骤一:推演:根据所传的实参来推演形参的类型
  • 步骤二:模板实例化:编译器生成对应的函数(模板实例化是通过函数模板去实例化生成对应具体的函数)

函数模板是一个蓝图,它本身并不是函数,是编译器用使用方式产生具体类型函数的模具,所以其实模板就是将本来应该我们做的重复的事情交给了编译器;

在编译器编译阶段,对于模板函数的使用,编译器需要根据传入的实参类型来推演生成对应类型的函数以供调用。比如:当double 类型使用函数模板的时候,编译器通过对实参类型的推演,将T确定为double 类型,然后专门产生一份专门处理double 类型的代码,对于字符类型也是如此;

注意: typename 是用来定义模板参数关键字,也可以使用class(切记:不能用struct 来代替class);

4、函数模板的实例化

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

1、隐式实例化:

让编译器根据实参推演模板参数的实际类型;

代码如下:

template<class T>
T Add(const T& left, const T& right)
{
	return left + right;
}

int main()
{
	int a1 = 10, a2 = 20;
	double d1 = 10.0, d2 = 20.0;
	Add(a1, a2);
	Add(d1, d2);

	return 0;
}

Add(a1,d1);是否可以调用成功?

该语句不能通过编译,因为在编译期间,当编译器要实例化的时候,需要推演其实参类型;通过实参a1 会将T推演为int ,但是通过实参 d1 又将T推演为 double 类型,但是模板参数列表中只有一个T,编译器无法确定此处到底应该将T确定为int 还是 double,于是就报错了;

需要注意的是,在模板中,编译器一般不会进行类型转换操作,因为一旦转换出了问题,编译器就需要背黑锅;

此处有两种处理方式:1、用户自己来强制转换 2、使用显式实例化

强制转换:Add((double)a1, d1);

2、显式实例化:

在函数名后面的<> 中指定模板参数的实际类型

使用代码如下:

int main()
{
	int a1 = 10, a2 = 20;
	double d1 = 10.0, d2 = 20.0;
	//Add((double)a1, d1);//强制类型转换
	Add<double>(a1, d1);//显式实例化

	return 0;
}

如果实参的类型不匹配,我们可以在函数名后的<> 中指定模板参数的实际类型,这就是显式实例化;由我们直接决定模板所要实例化这个函数的形参类型;

所以上述问题有两种解决方案:

解决方案一:强制类型转换

解决方案二:显式实例化

在方案一中,强制类型转换实参的类型,然后编译器根据实参的类型进行推演;本质:推演实例化;

显式实例化需要在调用函数名和实参之间添加一个 <> ,并在其中指定类型;

Q:显式实例化还有没有其他的应用场景?

  • 有些特殊的函数(eg. 该函数形参不使用模板类型),编译器无法通过其参数推演的时候就要使用显式实例化;

代码如下:

template<class T>
T* func(size_t n)
{
	return new T[n];
}

int main()
{
	func(10);//编译器无法通过实参推演并实例化
	return 0;
}

运行结果如下:

不能这样用的原因:实参传给形参,编译器会根据实参来推演模板类型,但是此处函数func 的形参是size_t 类型的,并没有使用模板类型,所以编译器无法进行推演而隐式实例化;但是我们可以直接告诉编译器此处的模板类型是什么,即让编译器显式实例化该函数;

显式实例化:

template<class T>
T* func(size_t n)
{
	return new T[n];
}

int main()
{
	func<int>(10);//显式实例化
	return 0;
}

5、模板参数的匹配原则

1、一个非模板函数可以和一个同名的函数模板同时存在,而且该函数模板还可以实例化为这个非模板函数;并且”有现成吃现成“

代码如下:

//专门处理int 类型数据的加法函数
int Add(int left, int right)
{
	return left + right;
}

//通用的加法函数
template<class T>
T Add(const T& left, const T& right)
{
	return left + right;
}

int main()
{
	int a1 = 10, a2 = 20;
	double d1 = 10.1, d2 = 20.2;

	//推演实例化
	cout << Add(a1, a2) << endl;
	cout << Add(d1, d2) << endl;

	return 0;
}

Q:为什么同名的函数模板可以与普通函数同时存在?

  • 因为C++中支持函数重载;

编译器的原则:有“现成”就是用“现成”的,没有“现成”就自己使用函数模板去实例化;即当存在同名的非模板函数与模板函数,调用的时候如果参数类型与非模板函数向匹配就会优先使用非模板函数,不匹配的时候编译器才会根据函数模板进行实例化;

模板的本质就是为了方便程序员,传不同类型的参数就可以实现相应的逻辑,而底层实际上还是在调用不同的函数;

而如果我们使用显式实例化,就意味着强制性地让编译器去使用函数模板实例化,代码如下:

//专门处理int 类型数据的加法函数
int Add(int left, int right)
{
	return left + right;
}

//通用的加法函数
template<class T>
T Add(const T& left, const T& right)
{
	return left + right;
}

int main()
{
	int a1 = 10, a2 = 20;
	double d1 = 10.1, d2 = 20.2;

	//推演实例化
	cout << Add(a1, a2) << endl;
	//显式实例化,强制编译器去使用函数模板去实例化
	cout << Add<int>(a1, a2) << endl;
	cout << Add(d1, d2) << endl;

	return 0;
}

2、对于非模板函数和同名函数模板,如果其他的条件相同,在调动的时候会优先调用非模板函数而不会从该模板中产生出一个实例;并且“在有现成吃现成的基础上,编译器还会选择更加匹配的”;

代码如下:

//非模板函数可以与模板函数同名
//专门处理int 类型数据的加法函数
int Add(int left, int right)
{
	return left + right;
}

//通用的加法函数
template<class T1,class T2>
T1 Add(T1 left, T2 right)
{
	return left + right;
}

int main()
{
	//与非模板函数类型完全匹配
	Add(1, 2);

	//模板函数可以生成更加匹配的版本,编译器根据实参生成更加匹配的Add函数
	Add(1, 2.0);
	return 0;
}

但是倘若此时只有一个不太匹配的“现成”,编译器也会选择隐式类型转换强制性地走;

3、模板函数不允许自动类型转换,但是普通函数可以进行自动类型转换;

小结:

在参数匹配的情况下,编译器会“有现成吃现成”;但如果参数不匹配并且此时有现成的不匹配(不匹配的非函数模板),以及匹配的“自己做”(匹配的函数模板),编译器会去调用更加匹配的;

三、类模板

之前用C++实现的Stack 之中,有typedef int STDateType;不能将typedef 理解为泛型,因为typedef 存在巨大的缺陷,无法让实例化出来的对象一个存放int类型的数据,一个存放double 类型的数据...即typedef 只能允许一个类型存在,不能同时多个类型的数据同时使用;

如果我们非要利用typedef 实现也是可以的,这样的话,我们就需要写成多个类来实现不同类型数据的存放,eg.StackInt、StackDouble...... 如果还有其他类型,需要拷贝主逻辑针对该类型重新实现一个类出来;这样做的话,单单就只有数据的类型不同,这些类的主逻辑大体都是相似,而又大幅度地增加了代码量,不利于维护;基于这样的问题,C++中还提供了类模板;

注:也正是因为C语言的语法无法支持“模板”这一概念以同时满足不同类型数据的需求,所以C语言库中不实现数据结构;

类模板与函数模板的区别:

  • 函数模板定义的参数只能给该函数使用,而类模板定义的参数是给整个类使用的;

1、类模板的定义格式

template<class T1,class T2,... ,class Tn>

class 类模板名

{

//类模板成员
};

也可以是:

template<typename T1,typename T2,... ,typename Tn>

class 类模板名

{

//类模板成员
};

使用代码如下:

//类模板
template<typename T>
class Stack
{
public:
	Stack(int n = 4)
	{
		_a = (T*)malloc(sizeof(T) * n);
		if (nullptr == _a)
		{
			perror("malloc 申请空间失败");
			return;
		}
		_capacity = n;
		_top = 0;
	}
private:
	T* _a;
	size_t _capacity;
	size_t _top;
};


int main()
{
    //必须显式实例化
	Stack<int> st1;
	Stack<double> st2;
	return 0;
}

需要注意的是,由于构造函数的形参不一定涉及T ,但构造函数之中又会使用T ,所以类模板的特点是必须显式实例化;

上例中的st1 与 st2 使用的并不是同一个类,是编译器根据同一个类模板实例化出来的不同的类;

2、类模板的实例化

类模板实例化与函数模板的实例化不同,类模板实例化需要在类模板名字后面跟<> ,然后将实例化类型放在<> 中即可,类模板名字并不是真正的类,而实例化的结果才是真正的类;

	//Stack 是类名,Stack<int>、Stack<double> 才是类型
    Stack<int> st1;//int
	Stack<double> st2;//double

接下来,我们还可以与根据类模板来优化之前我们所写的栈;(优化其中的小细节:引用传参、const 修饰、引用返回)

//类模板
template<typename T>
class Stack
{
public:
	Stack(int n = 4)
	{
		//_a = (T*)malloc(sizeof(T) * n);
		//if (nullptr == _a)
		//{
		//	perror("malloc 申请空间失败");
		//	return;
		//}
		//使用new 开辟空间
		_a = new T[n];
		_capacity = n;
		_top = 0;
	}
	
	void Push(const T& x)//引用传参、const修饰
	{
		//扩容判断
		if (_top == _capacity)
		{
			//走realloc 的逻辑
			int newcapacity = _capacity * 2;
			//异地扩容- 开辟新空间
			T* tmp = new T[newcapacity];
			memcpy(tmp, _a, sizeof(T) * _top);//拷贝数据
			delete[] _a;//释放旧空间

			_a = tmp;
			_capacity = newcapacity;
		}
		_a[_top++] = x;
	}

	void Pop()
	{
		assert(_top);
		_a[_top - 1] = -1;
		_top--;
	}

	const T& Top()//获取栈顶的数据,也需要用const 修饰
	{
		return _a[_top - 1];
	}

	~Stack()
	{
		delete[] _a;
	}

private:
	T* _a;
	size_t _capacity;
	size_t _top;
};

需要注意的是,在C++之中并没有renew ,所以扩容不能使用realloc ,需要使用new 、memcpy、delete 去模拟realloc 异地扩容的功能来满足扩容需求;在外部捕获异常即可;

对于获取栈顶的数据,初衷并不期望修改栈中的数据,所以Top的返回值为const 引用;

模板类中的成员函数声明与定义分离,分离的定义需要加上类模板:

需要注意的是,指定类域需要加上模板参数 T,而T的来源需要说清楚,所以要加上类模板;

如果写成:

如果存在多个类型的类,就会分不清楚这个Push 究竟是给谁用的了,并且在函数参数、函数体中也有可能会使用到模板参数T;所以在定义该函数的时候,需要声明其模板参数,其次是指定类域需要加上模板参数;修改如下:

其中还需要注意的是,类模板中成员函数不建议声明与定义分离到两个文件之中,否则会出现链接错误(与模板原理相冲突),原因此处暂不讲后续会有所提及;所以,类模板中成员函数的声明与定义一般是放在一个文件之中;

接下来,我们看一些stl_list.h 中的源码:

之所以stl源码中只有.h 文件而没有 .cpp 文件,就是因为类模板中成员函数的声明与定义不能分离到两个文件之中;短小的成员函数直接就在类中实现了,在类中实现的函数默认为内联函数,较长的成员函数便会在类中声明,类外定义;


总结

1、typename 是用来定义模板参数关键字,也可以使用class(切记:不能用struct 来代替class);

template<typename T1,typename T2,......,typename Tn>

返回类型   函数名(参数列表){} 

template<classT1,classT2,......,classTn>

返回类型   函数名(参数列表){} 

2、编译器根据模板来生成对应的函数:

  • 步骤一:推演:根据所传的实参来推演形参的类型
  • 步骤二:模板实例化:编译器生成对应的函数(模板实例化是通过函数模板去实例化生成对应具体的函数)

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

4、类模板定义格式:

template<class T1,class T2,... ,class Tn>

class 类模板名

{

//类模板成员
};

也可以是:

template<typename T1,typename T2,... ,typename Tn>

class 类模板名

{

//类模板成员
};

函数模板和类模板学习总结 封装:信息隐藏 继承:代码复用 多态:功能扩展 引用的本质是一个常指针,引用的内部实现是用指针实现 函数重载:形参个数不同,类型不同,顺序不同 用一个函数实现多个重载函数的功能:函数模板 函数的形参分为:数据类型 和 变量名  函数模板将数据类型当参数进行传递 解决的问题:将 数据类型 和算法 进行分离  专注于算法处理, 不需要关心处理的类型 函数模板:用 template 声明... 阅读详情

相关推荐

别让IO口保护二极管坑了你!实测讲解单片机电流倒灌的三种典型症状与防护

本文深入解析单片机电流倒灌的三大典型症状与防护方案,重点分析STM32等单片机在ADC采样异常、系统假死和通信速率异常中的表现。通过实测数据和电路设计建议,提供从基础二极管隔离到专业隔离器件的分级防护策略,帮助工程师有效预防和解决电流倒灌问题。

weixin_29280219的博客 344

函数模板

目录 1、什么是函数模板 2、函数模板的隐式实例化 3、函数模板的显示实例化 4、函数模板的显示具体化 5、函数模板的实例化与具体化的区别 6、测试程序 1、什么是函数模板 模板函数不是实际存在的函数,编译器不能为其生成可执行的代码。它只是一个用于生成函数定义的方案,只有在实际使用时,才能创建具体的实例函数(模板函数)。 #include <iostream> t...

Liu_Xiao_Ming的博客 663

从零部署思澈科技SiFli-Solution:避坑指南与实战排错

本文详细介绍了从零部署思澈科技SiFli-Solution开发环境的完整流程与实战排错指南。重点解析了Keil uVision5版本选择、Butterfli工具路径配置等关键步骤,并针对Keil路径报错、函数冲突等高频问题提供了具体解决方案,帮助开发者高效避坑,快速搭建稳定的嵌入式开发环境。

devops8pract的博客 529

函数模板.

函数是实现某种功能的存在,每个程序的编写都离不开函数,没需要实现一个功能往往都需要自定义一个函数,但有时候会发现,当需要实现的功能相似时,就会出现两个类似但又不能共用的函数,所以在C++中就存在着函数模板让这种类似的函数尽可能少的出现。接下来通过一个对数组排序的案例应用函数模板。 案例:实现用一个函数对不同类型的数组进行降序排序并把数组打印,算法要求:选择排序 首先测试字符类型数组,定义一个函数,在函数里定义一个无序的字符数组,如下: void test01() { //测试char数组 char ch

weixin_44540396的博客 744

无网络环境部署:手动获取并安装OneNote for Windows 10完整指南

本文提供了一份详尽的OneNote for Windows 10离线安装指南。针对无网络或内网隔离环境,详细介绍了如何从官方渠道获取正确的产品ID,利用第三方工具下载纯净的.appxbundle安装包,并解决系统兼容性与依赖框架问题。最后,通过PowerShell管理员命令完成安全部署,是IT管理员和高级用户在离线环境下部署UWP应用的实用参考。

loss4bartender的博客 495

rv1126 读取sensor输入,输出到屏幕显示【RK_MPI API接口】

rv1126 libdrm VO

学习记录 1万+

函数模板_类模板

项目需求: 实现多个函数用来返回两个数的最大值,要求能支持char类型、int类型、double类型变量 实际上,以上程序,只需要一个“函数”就可以搞定! 函数模板语法 所谓函数模板,实际上是建立一个通用函数,其函数类型和形参类型不具体指定,用一个虚拟的类型来代表。这个通用函数就称为函数模板。凡是函数体相同的函数都可以用这个模板来代替,不必定义多个函数,只需在模板中定义一次即可。在调用函数时系统会根据实参的类型来取代模板中的虚拟类型,从而实现了不同函数的功能。由以下三部分组成: 模板说明 + 函数定义 +

qq_35803412的博客 1245

VMware Workstation Pro 17 高效安装与激活指南

本文详细介绍了VMware Workstation Pro 17的高效安装与激活方法,包括系统要求、安装步骤、常见问题解决方案及性能优化技巧。通过专业的指导,帮助用户快速掌握这款强大的虚拟机软件,提升工作效率。

weixin_29322855的博客 402

模板元编程以及函数式编程

这样做相比于void func(N) 的好处是,如果作为模板N传入传输的话,N是一个编译期常量,对于不同的N,编译器都会针对其优化并生成单独的一份代码,从而可以做单独的优化。比如N=0 那么程序就不执行for语句,如果N=1,那么程序就只执行cout语句,而不执行for,如果N=3 那么可能自动unroll,如果N= 10/100/1000,那么程序可能会按照原来的for执行。而 func(N) 则是运行期的常量,编译器则无法自动优化。

zhuangtu1999的博客 407

基于ROS下的安卓手机图像和IMU跑ORB-SLAM3

接之前文章继续,手上没有现成的单目+IMU硬件,但是安卓手机几乎人人都有。因此,本文讲下如何用手机跑ORB-SLAM3的Mono和Mono_Inertial。 1. 手机与PC通信 基于ROS下的信息发布和订阅,手机和PC在一个局域网下进行信息(image和IMU)传输。 手机APK参考了github上的2个开源Android_Camera-IMU和android_ros_sensors,基于ros_java生成安卓APP,下载安装任一个APP到安卓手机,界面分别是这样: 手机和PC连一个无

h_372101的博客 1万+

回归预测 | MATLAB实现MPR多元多项式回归

回归预测 | MATLAB实现MPR多元多项式回归

机器学习之心的博客,关注并私信文章链接,获取对应文章源码和数据。 1645

c++_狄泰总结05泛型编程((函数/类模板)

泛型编程1)函数模板(C++泛型编程的一种)2)类模板类模板特化实例3)数组类模板**案例1:用最高效的方式来求 1+2+3+...+N****案例2: 数值型参数类模板**案例3:堆数组类模版构建(简易的线性表数据结构)4)智能指针类模板案例:编写智能指针类模板 ==》参照STL auto_ptr的设计STL中的智能指针(本质是对象)案例1:STL auto_ptr 使用案例QT中的智能指针案例...

camel_ant 553

基于Vivado MIG IP核的DDR3读写实验(top_rom_ddr/ddr_top)

一、前言 关于Vivado MIG IP核详细配置可以参考我之前的文章:基于Vivado MIG IP核的DDR3控制器(DDR3_CONTROL) 关于MIG IP核的用户端的接口时序可以参考这篇文章:XILINX 的 MIG IP(非AXI4)接口时序以及控制 二、实验内容 本次实验的内容主要是通过MIG IP核向DDR3读写数据,DDR3的接口时序由ddr_top模块提供: ddr_top模块的数据来源是wr_fifo,wr_fifo的数据实际来自top_sd_photo模块(本实验仿真

耐心的小黑的博客 3027

模版初阶【泛型编程】【函数模版】【类模版】

有关c++的模板初阶的学习 详细分析了【泛型编程】【函数模版】【类模版】的实现原理和过程。

aaa114514aaaa的博客 1737

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

C++模板编程:从函数模板到类模板的泛型编程实践

泛型编程是一种编程范式,其核心思想是编写与数据类型无关的通用代码,以提高代码的复用性和可维护性。其原理是通过模板机制,在编译时根据具体类型生成特化代码,从而实现类型安全的抽象。这种技术的价值在于能够显著减少代码冗余,提升开发效率,并支持构建高度灵活的数据结构和算法库。在实际应用场景中,泛型编程广泛用于标准模板库(STL)的容器(如vector、map)和算法(如sort、find)实现,以及构建通用工具类。本文以C++模板为例,深入探讨了函数模板和类模板的语法、实例化机制、模板实参推导等核心概念,并涵盖了模

weixin_34416754的博客 353

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

cpp中的函数模板

之前我们讲了函数重载,对一个不同参数类型的函数作出了不同的行为,但是其实有一个更加高效的方式,那就是函数模板,也叫泛型编程。或者模板元编程。下面是一个交换两个元素的例子我们只需要在调用时指定类型就可以我们也可以指定两种类型,下面的程序没有什么实际意义,就是为了展示一下

Lyajpunov的博客 1434

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

C++模板_函数模板_类模板

文章目录# C++ 模板## 函数模板## 类模板## 类模板实例:类 Stack<> # C++ 模板 模板是泛型编程的基础,泛型编程即以一种独立于任何特定类型的方式编写代码。 之前有,函数重载,如果有一个 sort排序函数,如果我们要对 int,double,string 都实现功能,就要重复写多个。 现在,有 函数模板,只用写一个,就可以实现多个不同的参数形式。 同理,也有对应的 类模板 模板是创建泛型类或函数的蓝图或公式。库容器,比如迭代器和算法,都是泛型编程的例子,它们都使用了模板

Mikchy的博客 511

【C++现代#7】模板元编程

作用:模板特化是处理泛型编程中“特殊情况”的关键工具。它让我们能够为特定的数据类型提供更高效、更安全或逻辑上更正确的实现。函数重载 vs. 函数模板特化:虽然有时可以使用函数重载来达到类似目的,但特化提供了更细粒度的控制,它仍然是同一个模板家族的成员,只是行为被定制。而重载则是定义一个全新的、独立的函数。在某些情况下,编译器选择重载函数比选择特化版本更复杂,因此通常推荐使用特化来处理特定类型。为什么函数模板不支持偏特化?这是C++标准委员会的一个设计决策。

island1314的博客 1045

C++模板(泛型编程)

本文主要介绍了C++中模板的基础知识和使用,包括模板的基本概念,函数模板和类模板的区别,模板的特化和偏特化等。

m0_62797154的博客 143

C++ 模板编程基础:泛型编程入门与实践

摘要: 本文系统讲解C++模板编程核心知识,涵盖函数模板、类模板、特化、非类型参数等基础,并深入模板元编程与C++20 Concepts等高级特性。通过图解和代码示例(如编译期阶乘计算),剖析模板"零开销抽象"的实现原理,给出GCC/Clang最新编译实践建议。内容兼顾STL底层机制与现代C++开发范式,帮助开发者掌握类型无关的泛型编程能力,实现高性能代码复用。文末提供学习路径和实战训练指引,适合从入门到进阶的C++开发者。

m0_57545130的博客 328

C++模板笔记

文章目录 ???C++模板 ??泛型编程 ??泛型是什么? ??泛型编程是什么? ??模板 ??函数模板 ??引论 ??什么是函数模板? ??实例 ??小结 ??模板的实例化 ??隐式实例化 ??显式实例化 ??类模板 ??引论 ??实例 ??注意点 ??总结 ???C++模板 ??泛型编程 ??泛型是什么? 泛型是一种可以替代所有类型的通用类型 不使用具体类型,使用通用类型进行编程,模板就是一个很好的使用泛型的例子 泛型,广泛的类型 ??泛型编程是什

web17886480312的博客 1367

6.C++的模板【由浅入深-C++】

本文介绍C++模板的相关内容。

插花弄玉的博客 1346

C++模板元编程

所谓的元编程就是编写直接生成或操纵程序的程序,C++模板为C++语言提供了元编程的能力。模板使 C++ 编程变得异常灵活,能实现很多高级动态语言才有的特性(语法上可能比较丑陋,一些历史原因见下文)。普通用户对 C++ 模板的使用可能不是很频繁,大致限于泛型编程,但一些系统级的代码,尤其是对通用性、性能要求极高的基础库(如 STL、Boost)几乎不可避免的都大量地使用 C++ 模板,一个稍有规模的大量使用模板的程序,不可避免的要涉及元编程(如类型计算)。本文就是要剖析 C++ 模板元编程的机制。

WHEgqing的专栏 1万+

【C++】函数模板和类模板

My_tools.h #include<iostream> using namespace std; template <class T> T My_min(T t1, T t2); template <typename T> T My_max(T t1, T t2); template <class T> void Swap(T t1...

Art1st_D的博客 326

C++函数模板:泛型编程核心机制与实战应用详解

泛型编程是现代编程语言中提升代码复用性和类型安全性的核心技术范式,其核心思想是编写与数据类型无关的通用算法和数据结构。在C++中,这一范式主要通过模板机制实现,编译器在编译时根据具体类型进行实例化,生成类型安全的特化代码。函数模板作为其重要组成部分,通过类型参数化实现了算法逻辑的抽象,其技术价值在于显著减少代码重复、增强类型安全并支持编译期多态。在工程实践中,函数模板广泛应用于标准模板库(STL)的算法组件(如排序、查找)、容器适配以及通用工具函数开发等场景。本文以C++函数模板为切入点,深入解析其**模板

weixin_30243533的博客 401

c++编程(9)——模板

欢迎来到博主的专栏——c++编程博主ID:代码小豪。

2301_77239666的博客 903
上一篇: 动态规划 - 斐波那契数列模型
下一篇: C++ - STL #什么是STL #STL的版本 #闭源开源 #STL的六大组件
秦少游在淮海
博客等级 码龄3年 1071粉丝 88原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值