【C++】详细介绍模版初阶—函数模版、类模板

这篇具有很好参考价值的文章主要介绍了【C++】详细介绍模版初阶—函数模版、类模板。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


ヾ(๑╹◡╹)ノ" 人总要为过去的懒惰而付出代价ヾ(๑╹◡╹)ノ"
【C++】详细介绍模版初阶—函数模版、类模板,C++,笔记,c++,前端


一、泛型编程

泛型编程:编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础。【不是针对某种类型】
template模版关键字
template< class T>
template< typename T>

  • 模版的参数学习,可以类比函数参数。
  • 模版参数传递的是类型;函数参数传递的是对象值。
  • 模版的定义和声明不支持分别在两个文件里面【会出现链接错误,所有的链接错误都是符号表找不到】因为编译器的模版T是无法确定的,无法生成符号表。
  • 模版是不支持声明与定义分别放到.h和.cpp中,一般都是需要放到一个文件中。有些地方就会命名成.hpp【头文件和定义实现内容合并到一起】但是并不是必须是.hpp,.h也是可以的。

解决办法【声明与定义分离,出现链接错误】

  1. 显示实例化指定(麻烦,不建议)
//声明
template
void Swap<int>(int& left, int& right);

template
class Vector<int>;

template
class Vector<double>;
//原因是因为声明没有类型,那么我们就把类型给写出来
  1. 不分离两个文件中

二、函数模版

2.1 函数模版概念

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

2.2 函数模版格式

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

template<typename T>//也可以是class T
void Swap(T& left, T& right)
{
	T tmp = left;
	left = right;
	right = tmp;
}
//函数模版

注意:typename是用来定义模板参数关键字,也可以使用class(切记:不能使用struct代替class)【Swap库里面有,不用自己实现】
声明与定义

//声明
template<typename T>
void Swap(T& left, T& right);

//定义
template<typename T>
void Swap(T& left, T& right)
{
	T tmp = left;
	left = right;
	right = tmp;
}
//函数模版

注意定义写的格式

2.3 函数模版的原理

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

函数模版的类型是编译器根据实参传递给形参,推演出来的。如果不能自动推演,我们就需要显示实例化,指定模版参数。
类模板的类型显示实例化,明确指定的。

2.4 函数模版的实例化

用不同类型的参数使用函数模板时,称为函数模板的实例化。
模板参数实例化分为:隐式实例化显式实例化
1. 隐式实例化:让编译器根据实参传递给形参,推演模板参数的实际类型

template<typename T>//也可以是class T
void Swap(T& left, T& right)
{
	T tmp = left;
	left = right;
	right = tmp;
}
//函数模版

int main()
{
	int a = 1;
	int b = 2;
	Swap(a, b);//编译器根据实参传递给形参,判断为int
	double c = 1.2;
	double d = 2.3;
	Swap(c, d);//编译器根据实参传递给形参,判断为double
	return 0;
}

当参数类型不同时:

template<typename T>
T Add(const T& left, const T& right)//常量,需要有const
{
	return left + right;
}
int main()
{
	int a = 1;
	double c = 2.1;
	Add<int>(a, c);//c这里有一个隐式类型转换
	Add<double>(a, c);

	Add(a,(int)c);//c这里有一个隐式类型转换
	Add((double)a, c);
	return 0;
}

2. 显式实例化:在函数名后的<>中指定模板参数的实际类型

template<typename T>
T* func(int n)
{
	terurn new T[n];//new n个对象,,,,无法推导出T的类型
}
int main()
{
	int* p1 = func<int>(10);//函数模版显示实例化
	return 0;
}

如果类型不匹配,编译器会尝试进行隐式类型转换,如果无法转换成功编译器将会报错。

函数模版的类型是编译器根据实参传递给形参,推演出来的。如果不能自动推演,我们就需要显示实例化,指定模版参数。

2.5 函数模版的匹配原则

  1. 一个非模板函数【专门的函数】可以和一个同名的函数模板同时存在,而且该函数模板还可以被实例化为这个非模板函数。
  2. 对于非模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用非模板函数而不会从该模板产生出一个实例。如果模板可以产生一个具有更好匹配的函数, 那么将选择模板。
  3. 模板函数不允许自动类型转换,但普通函数可以进行自动类型转换

三、类模版

3.1 类模版定义

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

类模板不是具体的类,实例化才是真正的类。

template<class T>
class Stack
{
public:
    // 使用析构函数演示:在类中声明,在类外定义。
	~Vector();
	//……
	void push(T x)
	{

	}

private:
	T* _a;
	int _top;
};
//类模板中函数放在类外进行定义时,需要加模板参数列表,每一个函数都需要加模板参数列表
template <class T>
Vector<T>::~Vector()
{
if(_pData)
     delete[] _pData;
_size = _capacity = 0;
}

int main()
{
	Stack<int> s1;
	s1.push(1);
	Stack<double> s2;
	s2.push(2.1);
	return 0;
}

类模板中函数放在类外进行定义时,需要加模板参数列表

3.2 类模版实例化

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

Vector类名,Vector< int >才是类型 Vector < int > s1; Vector< double > s2;


总结

以上就是今天要讲的内容,本文详细的介绍了函数模版和类模板。希望给友友们带来帮助!文章来源地址https://www.toymoban.com/news/detail-677011.html

到了这里,关于【C++】详细介绍模版初阶—函数模版、类模板的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Python框架【模板继承、继承模板实战、装饰器、蓝图(介绍、单文件、目录结构、模版文件、静态文件 url_for函数子域名实现)】(五)

    👏作者简介:大家好,我是爱敲代码的小王,CSDN博客博主,Python小白 📕系列专栏:python入门到实战、Python爬虫开发、Python办公自动化、Python数据分析、Python前后端开发 📧如果文章知识点有错误的地方,请指正!和大家一起学习,一起进步👀 🔥如果感觉博主的文章还不错的

    2024年02月10日
    浏览(48)
  • 初阶C语言——特别详细地介绍函数

     💓作者简介: 加油,旭杏,目前大二,正在学习 C++ , 数据结构 等👀 💓作者主页:加油,旭杏的主页👀 ⏩本文收录在:再识C进阶的专栏👀 🚚代码仓库:旭日东升 1👀 🌹欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖💖        从标题也能看出来,我们有要进行 超详细

    2024年02月14日
    浏览(34)
  • C++模版初阶

    如下的交换函数中,它们只有类型的不同,应该怎么实现一个通用的交换函数呢? 使用函数重载虽然可以实现,但是有一下几个不好的地方:         1. 重载的函数仅仅是类型不同,代码复用率比较低,只要有新类型出现时,就需要用户自己增加对应的函数;       

    2024年02月05日
    浏览(39)
  • 【C++】模版初阶

    目录 泛函编程 函数模版 概念 格式 原理 实例化 模版函数的匹配原则 类模板 定义格式 如何实现一个通用的交换函数呢? 使用函数重载虽然可以实现,但是有几个不好的地方: 1. 重载的函数仅仅是类型不同,代码复用率比较低,只要有新类型出现时,就需要用户自己增加对

    2024年02月19日
    浏览(37)
  • C++模版初阶讲解

    今日为大家分享C++的模版,这里先把模版的初阶讲解一下,以后再讲解模版进阶! 在我们进行学习的编程中,常常会有许多函数的功能相同,有些不同点可能就是其中的数据类型不同!如果我们统统进行函数重载的话,其实也能解决问题,例如,实现两个数的交换! 但是函

    2024年02月06日
    浏览(38)
  • 【初阶C语言3】特别详细地介绍函数以及在初阶中重要的算法——递归

     💓作者简介: 加油,旭杏,目前大二,正在学习 C++ , 数据结构 等👀 💓作者主页:加油,旭杏的主页👀 ⏩本文收录在:再识C进阶的专栏👀 🚚代码仓库:旭日东升 1👀 🌹欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖💖        从标题也能看出来,我们有要进行 超详细

    2024年02月08日
    浏览(45)
  • 【C++从入门到放弃】模板介绍(函数模板、类模板)

    🧑‍💻作者: @情话0.0 📝专栏:《C++从入门到放弃》 👦个人简介:一名双非编程菜鸟,在这里分享自己的编程学习笔记,欢迎大家的指正与点赞,谢谢!   以我们之前所学的知识,假如要实现一个通用的加法函数,那么可以通过函数重载的方式来实现。 使用函数重载虽

    2023年04月14日
    浏览(41)
  • 【初阶C语言】关于scanf函数的超详细介绍和多组输入

    感谢各位可以光临娥子的作品   我们学习一个函数,要围绕三个点 :1.函数是什么  2.函数的用法   3.注意的细节 认识一个 函数,我们需要了解他的功能、返回值、接收的参数三个方面 函数原型  (1)功能介绍          scanf函数是一个输入函数 ,所以接收的参数类型需

    2024年02月08日
    浏览(53)
  • C++学习笔记-第11单元 标准模板库介绍

    注:本部分内容主要来自中国大学MOOC北京邮电大学崔毅东的 《C++程序设计》课程。 注:94条 C++程序规范。   本单元重点是对标准模板库中的 顺序容器 、 关联容器 的使用,以及 如何创建迭代器以遍历容器 。在使用容器时要注意不同容器的实现方式对遍历、搜索、删除、

    2024年02月13日
    浏览(39)
  • 【C++初阶】第六站 : 模板初阶

    前言: 本章知识点:泛型编程、函数模板、类模板 专栏: C++初阶 目录 泛型编程 函数模板 1.函数模板概念 2.函数模板格式 3.函数模板的原理 4.函数模板的实例化 5.模板参数的匹配原则 类模板 类模板的定义格式 类模板的实例化 如何实现一个通用的交换函数呢? 代码如下:

    2024年03月17日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包