c++(模版)

news2024/11/14 15:22:58

目录

函数模板格式 

 函数模版原理

函数模板的实例化

模板参数的匹配原则

类模板


函数模板格式 


template<typename T1, typename T2,......,typename Tn>
返回值类型 函数名(参数列表){}
 

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

 函数模版原理

在编译器编译阶段,对于模板函数的使用,编译器需要根据传入的实参类型来推演生成对应
类型的函数以供调用

函数模板概念

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

函数模板的实例化

不同类型的参数使用函数模板时,称为函数模板的实例化

模版不建议声明和定义分离到两个文件.h 和.cpp会出现链接错误
模板参数实例化分为:隐式实例化和显式实例化

隐式实例化(模板实参省略):让编译器根据实参推演模板参数的实际类型   Add(a1, (int)d1)

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);
	cout << Add(a1, (int)d1) << endl;
	return 0;
}

显式实例化:在函数名后的<>中指定模板参数的实际类型    Add<int>(a1, d1)

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);
	cout << Add(a1, (int)d1) << endl;
	cout << Add<int>(a1, d1) << endl;
	return 0;
}

模板参数的匹配原则

1. 一个非模板函数可以和一个同名的函数模板同时存在,而且该函数模板还可以被实例化为这个非模板函数


// 专门处理int的加法函数
int Add(int left, int right)
{
	return left + right;
} 
//通用加法函数
template<class T>
T Add(T left, T right)
{
	return left + right;
} 
void Test()
{
	Add(1, 2); // 与非模板函数匹配,编译器不需要特化
	Add<int>(1, 2); // 调用编译器特化的Add版本
}
int main()
{
	Test();
}

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;
	}
	void Test()
	{
		Add(1, 2); // 与非函数模板类型完全匹配,不需要函数模板实例化
		Add(1, 2.0); // 模板函数可以生成更加匹配的版本,编译器根据实参生成更加匹配的
	}
int main()
{
	Test();
}

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

类模板

template<class T1, class T2, ..., class Tn>
class 类模板名
{
// 类内成员定义
};

// 类模版
template<typename T>
class Stack
{
	public :
	Stack(size_t capacity = 4)
	{
		_array = new T[capacity];
		_capacity = capacity;
		_size = 0;
	} 
	~Stack()
	{
		delete[] _array;
		_array = nullptr;
		_size = _capacity = 0;
	}
	void Push(const T& data)
	{
		if (_size == _capacity)
		{
			T* tmp = new T[_capacity * 2];
			memcpy(tmp, _array, sizeof(T) * _size);
			delete[]_array;

			_array = tmp;
			_capacity *= 2;
		}
		_array[_size++] = data;
	}
private:
	T* _array;
	size_t _capacity;
	size_t _size;
};

int main()
{
	//类模板都是显示实例化
	Stack<int> s1;
	s1.Push(1);
	s1.Push(2);
	s1.Push(3);
	s1.Push(4);
	Stack<double> s2;
	s2.Push(1.1);
	s2.Push(2.1);
	s2.Push(3.1);
	s2.Push(4.1);
}
// 类模版
template<typename T>
class Stack
{
	public :
	Stack(size_t capacity = 4)
	{
		_array = new T[capacity];
		_capacity = capacity;
		_size = 0;
	} 
	~Stack()
	{
		delete[] _array;
		_array = nullptr;
		_size = _capacity = 0;
	}
	void Push(const T& data);
private:
	T* _array;
	size_t _capacity;
	size_t _size;
};

//声明和定义分离时,需要再写一次类模板
template<typename T>
void Stack<T>::Push(const T& data)
{
	if (_size == _capacity)
	{
		T* tmp = new T[_capacity * 2];
		memcpy(tmp, _array, sizeof(T) * _size);
		delete[]_array;

		_array = tmp;
		_capacity *= 2;
	}
	_array[_size++] = data;
}
int main()
{
	//类模板都是显示实例化
	Stack<int> s1;
	s1.Push(1);
	s1.Push(2);
	s1.Push(3);
	s1.Push(4);
	Stack<double> s2;
	s2.Push(1.1);
	s2.Push(2.1);
	s2.Push(3.1);
	s2.Push(4.1);
}

 知识点

template <typename T, int size>
class Array {
public:
    T arr[size]; // 使用非类型模板参数
};
template <typename T>
void func(T arg) {
    // 函数体
}
//T是一个类型模板参数

 可用来创建动态增长和减小的数据结构(模板可以具有非类型参数,用于指定大小,可以根据指定的大小创建动态结构)

模板类型无关,提高了代码复用性

模板运行时不检查数据类型,也不保证类型安全,相当于类型的宏替换

平台无关的,可移植性(只要支持模板语法,模板的代码就是可移植的)

模板实参省略意思为隐式实例化

类模板与模板类所指的不是同一概念(类模板是一个类家族,模板类是通过类模板实例化的具体类)   

(MyClass 是一个类模板,而 MyClass<int>MyClass<double> 和 MyClass<std::string> 是模板类的具体实例)

类模板中的成员函数全是模板函数(所有类模板的成员函数,放在类外定义时,需要在函数名前加类名,而类名实际为ClassName<T>,所以定义时还需加模板参数列表)

template<class T>
   size_t Stack<T>::size(){
        return _size;
   }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1972610.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

cesium的flyTo在飞行完成后渲染

viewer.camera.flyTo({}); 替换自己要渲染的labe img等 viewer.camera.flyTo({destination: Cesium.Cartesian3.fromDegrees(lon,lat,height), // 飞行目的地&#xff0c;视角高度duration: 3, // 飞行所用时间// 飞行完成后的事件complete: function() {viewer.camera.flyTo…

pytorch: cpu,cuda,tensorRt 推理对比学习

0&#xff1a;先看结果 针对resnet模型对图片做处理 原图结果 分别使用cpu&#xff0c;cuda&#xff0c;TensorRt做推理&#xff0c;所需要的时间对比 方法时间cpu13s594mscuda711mstensorRt 113ms 项目地址&#xff1a; GitHub - july1992/Pytorch-vily-study: vily 学…

KubeVirt虚拟机存储及网络卸载加速解决方案

1. 方案背景 1.1. KubeVirt介绍 随着云计算和容器技术的飞速发展&#xff0c;Kubernetes已成为业界公认的容器编排标准&#xff0c;为用户提供了强大、灵活且可扩展的平台来部署和管理各类应用。然而&#xff0c;在企业的实际应用中&#xff0c;仍有许多传统应用或遗留系统难…

电脑缺少directx怎么办?电脑dll修复详细教程!7种方法!

DLL&#xff08;动态链接库&#xff09;文件是Windows操作系统中非常重要的组成部分&#xff0c;它们包含了程序运行所需的代码和数据。然而&#xff0c;由于各种原因&#xff0c;如系统更新、软件卸载不当或病毒感染&#xff0c;DLL文件有时会丢失或损坏&#xff0c;导致程序无…

day18 Java流程控制——Scanner进阶使用

day18 Java流程控制——Scanner进阶使用 本章目录 day18 Java流程控制——Scanner进阶使用1. 什么是Scanner&#xff1f;2. Scanner进阶使用&#xff08;实例&#xff09;2.1 整数&小数的输入输出2.2 我们可以输入多个数字&#xff0c;并求其总和与平均数&#xff0c;每输入…

96年高中程序员年收入30万

互联网创业交流群&#xff0c;从昨天晚上8.1建军节开始建群&#xff0c;到今天中午已经突破200人了。 这里面有我的朋友&#xff0c;也有马总的朋友&#xff0c;当然不管是谁的朋友&#xff0c;进来了大家都是一家人。 以后在不违反原则的情况下&#xff0c;希望大家能和谐相…

建筑业数据挖掘:Scala爬虫在大数据分析中的作用

数据的挖掘和分析对于市场趋势预测、资源配置优化、风险管理等方面具有重要意义&#xff0c;特别是在建筑业这一传统行业中。Scala&#xff0c;作为一种强大的多范式编程语言&#xff0c;提供了丰富的库和框架&#xff0c;使其成为开发高效爬虫的理想选择。本文将探讨Scala爬虫…

《Cloud Native Data Center Networking》(云原生数据中心网络设计)读书笔记 -- 03 云原生网络操作系统

本章要回答的问题&#xff1a; 云原生网络操作系统的主要需求是什么?什么是 OpenFlow 和软件定义网络? 它们适用什么样的场景?网络解耦中网络操作系统有哪些可能的选择?这些模型与云原生 NOS 的需求相比是怎样的? 网络设备的新需求 云原生时代中网络设备需要满足以下要求…

揭秘对话式搜索中的广告检测——Detecting Generated Native Ads in Conversational Search

Detecting Generated Native Ads in Conversational Search | Companion Proceedings of the ACM on Web Conference 2024https://dl.acm.org/doi/abs/10.1145/3589335.3651489 1. 概述 大型语言模型(LLMs)已成为构建对话式搜索引擎与检索增强生成系统的主流标准。然而,在大…

python packages是什么意思

package指的就是包&#xff0c;它是一个有层次的文件目录结构&#xff0c;它定义了由n个模块或n个子包组成的python应用程序执行环境。通俗一点&#xff1a;包是一个包含__init__.py 文件的目录&#xff0c;该目录下一定得有这个__init__.py文件和其它模块或子包。 但是这会分…

【传知代码】疯狂交互学习的BM3推荐算法(论文复现)

在当今信息爆炸的时代&#xff0c;我们每天接触的数据量已经超出我们大脑的处理能力。在这个背景下&#xff0c;个性化推荐系统以其独特的能力和智能化的算法引起了广泛关注。其中&#xff0c;基于行为的推荐系统成为了引领潮流的前沿技术之一&#xff0c;本文将深入探讨疯狂交…

未来已来:AI在提升企业客户服务质量与效率中的应用

随着人工智能&#xff08;AI&#xff09;技术的飞速发展&#xff0c;其在企业客户服务领域的应用正以前所未有的速度改变着我们的服务模式。AI技术的引入&#xff0c;不仅极大地提升了客户服务的效率&#xff0c;还显著提高了客户满意度&#xff0c;为企业创造了新的竞争优势。…

【kubernetes】kubeadm部署k8s集群

1、环境准备 master01: 192.168.10.25master02: 192.168.10.26master03: 192.168.10.27node01: 192.168.10.28node02: 192.168.10.29负载均衡器1&#xff1a;192.168.10.30负载均衡器2&#xff1a;192.168.10.31 //所有节点&#xff0c;关闭防火墙规则&#xff0c;关闭selinu…

秋招突击——算法训练——8/1——用友集团笔试

文章目录 引言正文小友的生产线个人实现参考实现 小友策划游戏人物个人实现参考实现 最佳工作任务安排个人实现参考实现 大众评分最高的一次旅程 总结 引言 今天晚上七点钟到九点钟是用友集团的笔试&#xff0c;作为今天算法练习的主要内容&#xff01;具体怎么样&#xff0c;…

MinIO DataPod:百亿亿次级计算的参考架构

现代企业通过其数据来定义自己。这需要用于 AI/ML 的数据基础设施&#xff0c;以及作为现代数据湖基础的数据基础设施&#xff0c;该数据基础设施能够支持商业智能、数据分析和数据科学。如果他们落后、起步或使用 AI 获得高级见解&#xff0c;则情况确实如此。在可预见的未来&…

又一个GPT4级的模型免费了?MiniMax史诗级更新

又有一个超性价比的国产大模型出现了&#xff01;这里是智匠AI&#xff0c;MiniMax刚刚对他们的主力模型abab6.5s&#xff0c;进行了大幅降价&#xff0c;输入和输出成本都达到了1元/百万tokens。我们今天就来进行评测这款abab6.5s。 abab6.5s在文科任务、内容理解、文字生成及…

WebKit引擎:探索现代网页渲染的幕后魔法!

WebKit 是一个开源的浏览器引擎&#xff0c;它负责解析和渲染网页内容&#xff0c;包括HTML、CSS和JavaScript。WebKit的工作流程涵盖了加载资源、解析文档、应用样式、布局渲染树等一系列步骤&#xff0c;最终将网页内容呈现在用户的屏幕上。 WebKit简介 WebKit是一个开源的浏…

Python在气象与海洋中的应用

Python是功能强大、免费、开源&#xff0c;实现面向对象的编程语言&#xff0c;能够在不同操作系统和平台使用&#xff0c;简洁的语法和解释性语言使其成为理想的脚本语言。除了标准库&#xff0c;还有丰富的第三方库&#xff0c;并且能够把用其他语言&#xff08;C/C、Fortran…

Python SyntaxError: unexpected EOF while parsing

Python SyntaxError: unexpected EOF while parsing 在Python编程中&#xff0c;SyntaxError: unexpected EOF while parsing是一个常见的错误&#xff0c;通常发生在Python解释器在源代码中找到意外的文件结尾&#xff08;EOF&#xff0c;即End Of File&#xff09;时。这个错…

大模型LLM关键技术手段

大语言模型&#xff08;LLM&#xff09;是人工智能领域的一个突破性进展&#xff0c;它通过多种技术手段实现对自然语言的理解和生成。用比较通俗的话来列举一些我认为比较关键的技术手段&#xff1a; 深度学习技术&#xff1a;就像我们通过不断学习来掌握知识一样&#xff0c;…