首页 > 编程语言 >C++ 模板(函数模板)

C++ 模板(函数模板)

时间:2024-09-05 14:05:02浏览次数:6  
标签:arr 函数 int C++ template 类型 模板

模板

模板介绍

C++提供了函数模板(function template)。所谓函数模板。实际上是建立一个通用函数,其函数类型和形参类型不具体制定,用一个虚拟的类型来代表。这个通用函数就称为函数模板。凡事函数体相同的函数都可以使用这个模板代替,不必定义多个函数,只需在模板中定义一次即可。在调用函数时系统会根据实参的类型来取代模板中的虚拟类型,从而实现不同的函数功能。

C++提供了两种模板机制:函数模板类模板

意义:

  • 模板把函数或类要处理的数据类型参数化,表现为参数的多态性,称为类属。
  • 模板用于表达逻辑结构相同,但具体数据元素类型不同的数据对象的通用行为。

函数模板

下面举例说明一下函数模板的具体用法。

假设有两个需求:

  • 设计一个函数,实现两个int变量的值的交换
  • 设计一个函数,实现两个double变量的值的交换
void mySwap(int &a, int &b){
	int tmp = a;
	a = b;
	b = tmp;
}
void mySwap(double &a, double &b){
	double tmp = a;
	a = b;
	b = tmp;
}

如果还有需求要交换其他类型的变量,还需要继续添加函数,而代码几乎一致。并且一旦需求有变更,每个函数都要一个一个修改,非常繁琐且重复。

发现两个函数逻辑结构完全相同,只有变量类型不同,如果能设计一个通用的函数,能够把类型当做参数传递到这个函数中,就简单多了——这就是函数模板

定义

  • 用法:template<typename T>

template:模板关键字
typename:定义虚拟类型关键字,也可以使用class
T:定义的一个虚拟的类型,在这里暂时不确定是什么类型,等到调用这个函数的时候就可以确定了

template<typename T>
void mySwap(T &a, T &b){
	T tmp = a;
	a = b;
	b = tmp;
}

int main(){

	int a = 10, b = 20;
	double x = 3.14, y = 9.9;

	// 显式指定类型
	mySwap<int>(a, b);

	// 可以自动根据实参的类型进行推导
	mySwap(a, b);
	mySwap(x, y);

	cout << "a:" << a << endl;
	cout << "b:" << b << endl;
	cout << "x:" << x << endl;
	cout << "y:" << y << endl;

	system("pause");
	return 0;
}

函数模板使用案例

  • 需求
    • 定义一个函数模板,实现对数组中元素进行升序排序
    • 定义一个函数模板,实现将一个数组中元素拼接成为字符串返回
// 定义一个函数模板,实现对数组中元素进行升序排序
template<class T>
void mySort(T arr[], int len){
	for (int i = 0; i < len; i++){
		for (int j = i; j < len; j++){
			if (arr[i] > arr[j]){
				T tmp = arr[i];
				arr[i] = arr[j];
				arr[j] = tmp;
			}
		}
	}
}

// 定义一个函数模板,实现将一个数组中元素拼接成为字符串返回
template<class T>
void showArray(T arr[], int len){
	cout << "[";
	for (int i = 0; i < len - 1; i++){
		cout << arr[i] << ",";
	}
	cout << arr[len - 1] << "]" << endl;
}

int main(){
	// 定义一个int[]
	int array1[] = { 1, 3, 5, 7, 9, 0, 8, 6, 4, 2 };
	int len1 = sizeof(array1) / sizeof(int);
	mySort(array1, len1);
	showArray(array1, len1);

	// 定义一个double[]
	double array2[] = { 3.14, 9.28, 3, 3.44, -9.2, 8.22 };
	int len2 = sizeof(array2) / sizeof(double);
	mySort(array2, len2);
	showArray(array2, len2);

	// 定义一个char[]
	char array3[] = { 'a', 'l', '1', 'm', 'k' };
	int len3 = sizeof(array3) / sizeof(char);
	mySort(array3, len3);
	showArray(array3, len3);

	system("pause");
	return 0;
}

函数模板与普通函数

函数模板和普通函数在调用的时候需要注意:

  • 普通函数的调用是可以发生自动类型转换的;而函数模板调用不允许发生自动类型转换
  • 如果调用函数的时候,实参既可以匹配普通函数,又可以匹配函数模板,则优先匹配普通函数

函数模板重载

函数模板虽然很通用,但并不是万能的,有时候也会出现不适配的情况

template<class T>
bool compare(const T& t1, const T& t2) {
    return t1 > t2;
}

对于上述函数模板,如果比较的类型设置为自定义类型(如Person类型),则会出现无法比较的问题。

而函数模板的重载,就是为了解决特定对象的问题,通过函数模板的重载,可以为这些特定的数据类型提供具象化的模板

class Person {
public:
    int age;
};

template<class T>
bool compare(const T& t1, const T& t2) {
    return t1 > t2;
}

template<>
bool compare<Person>(const Person& p1, const Person& p2) {
    return p1.age > p2.age;
}


int main() {

    Person p1;
    p1.age = 15;

    Person p2;
    p2.age = 12;

    cout << compare(p1, p2) << endl;


    return 0;
}

标签:arr,函数,int,C++,template,类型,模板
From: https://www.cnblogs.com/1873cy/p/18398002

相关文章

  • 【生日视频制作】星空木屋霓虹灯爱心形照片AE模板修改文字软件生成器教程特效素材【AE
    生日视频制作教程星空木屋霓虹灯爱心形照片AE模板修改文字特效广软件告生成神器素材祝福玩法AE模板替换工程怎么如何做的【生日视频制作】星空木屋霓虹灯爱心形照片AE模板修改文字软件生成器教程特效素材【AE模板】生日视频制作步骤:安装AE软件下载AE模板把AE模板......
  • 【生日视频制作】白色卡车行万里路车身改字2版AE模板修改文字软件生成器教程特效素材
    生日视频制作教程白色卡车行万里路车身改字2版AE模板修改文字特效广软件告生成神器素材祝福玩法AE模板工程怎么如何做的【生日视频制作】白色卡车行万里路车身改字2版AE模板修改文字软件生成器教程特效素材【AE模板】生日视频制作步骤:安装AE软件下载AE模板把AE模......
  • 字符函数和字符串函数
    在编程的过程中,我们经常要处理字符和字符串,为了方便操作字符和字符串,C语言标准库中提供了⼀系列库函数,接下来我们就学习⼀下这些函数。目录1.1字符分类函数1.2字符转换函数例子:代码结果2.strlen3.strcpy4.strcat5.strcmp6.strstr7.strtok8.strerror9.模拟实现9.1str......
  • OPenCV结构分析与形状描述符(5)查找图像中的连通组件的函数connectedComponents()的使用
    操作系统:ubuntu22.04OpenCV版本:OpenCV4.9IDE:VisualStudioCode编程语言:C++11算法描述connectedComponents函数计算布尔图像的连通组件标签图像。该函数接受一个具有4或8连通性的二值图像,并返回N,即标签总数(标签范围为[0,N-1],其中0代表背景标签)。ltype参数指......
  • OPenCV结构分析与形状描述符(3)计算一个点集的最小外接矩形的函数boundingRect()的使用
    操作系统:ubuntu22.04OpenCV版本:OpenCV4.9IDE:VisualStudioCode编程语言:C++11算法描述计算一个点集的最小右上边界矩形或灰度图像中的非零像素。该函数计算并返回指定点集或灰度图像中非零像素的最小右上边界矩形。在OpenCV中,boundingRect函数用于找到一个点集的最......
  • C++: std::once_flag 和 std::call_once
    std::once_flag和std::call_oncestd::once_flag和std::call_once是C++11引入的同步原语,用于确保某个函数在多线程环境中只被执行一次。它们位于头文件中,主要用于实现线程安全的初始化操作。std::once_flag概述类型:std::once_flag是一个结构体,用于记录某个函数......
  • C++ 原子变量atomic variable
    原子变量原子变量(atomicvariable)是C++11引入的一种同步机制,用于在多线程环境中进行无锁的、线程安全的操作。原子变量的操作是不可分割的,即在执行过程中不会被其他线程中断,从而避免了数据竞争和不一致的问题。原子变量位于头文件中。基本概念原子性原子性:一个操作是......
  • 基于云函数的自习室预约微信小程序+LW示例参考
    全阶段全种类学习资源,内涵少儿、小学、初中、高中、大学、专升本、考研、四六级、建造师、法考、网赚技巧、毕业设计等,持续更新~文章目录@[TOC](文章目录)1.项目介绍2.项目部署3.项目部分截图4.获取方式1.项目介绍技术栈+工具:云数据库+云函数+JS+原生微信小......
  • C++和Python混合编程——C++调用Python入门
    大纲代码结构初始化Python解释器获取GIL为什么需要GIL?GIL的影响导入Python模块并执行代码释放GIL终止Python解释器完整代码编译执行结果项目地址在《C++和Python混合编程——Python调用C++入门》一文中,我们熟悉了Python调用C++编译的动态库的方法。但是作......
  • C++11新特性
    C++11主要新特性有类的初始化与函数、新增关键字、std库新特性、lambda表达式、智能指针、线程1.关键字()nullptr取代NULL、0()constexpr:显式声明函数返回值、变量是一个常量表达式()auto:对变量类型推导,()decltype:对表达式类型推导,用法为decltype(表达式)()using:声明使用的命......