C++——模板初阶与泛型编程

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

C++——模板初阶与泛型编程

C++——模板初阶与泛型编程

💐专栏导读

🌸作者简介:花想云,在读本科生一枚,致力于 C/C++、Linux 学习。

🌸本文收录于 C++系列,本专栏主要内容为 C++ 初阶、C++ 进阶、STL 详解等,专为大学生打造全套 C++ 学习教程,持续更新!

🌸相关专栏推荐:C语言初阶系列C语言进阶系列数据结构与算法

💐文章导读

本章我们将学习模板,与泛型编程初次见面。C++相比于C语言有这么多丰富的接口与类型,都源于泛型编程。本章的内容为模板初阶知识,为接下来的STL学习打下坚实的基础。

🌷引例

如何实现一个通用的交换函数(swap)呢?我们已经学过函数重载的使用,函数重载在这种场景下貌似作用很大。

void Swap(int& a, int& b)
{
	auto tmp = a;
	a = b;
	b = tmp;
}

void Swap(double& a, double& b)
{
	auto tmp = a;
	a = b;
	b = tmp;
}

void Swap(char& a, char& b)
{
	auto tmp = a;
	a = b;
	b = tmp;
}
//...

虽然函数重载可以实现,但是有点吃力。最糟心的事儿是明明这些函数几乎都长一个样子,仅仅是参数类型不同而已,但是每多一个类型就得写一个对应的重载函数。

那么有什么办法能做到一劳永逸呢?能否做到告诉编译器:我给你一个模板,你来帮我实现每个函数,只是换一下参数类型就OK了?

这就是我们今天要讲到的模板——模板是泛型编程的基础。模板不仅适用于函数,也适用于

🌷函数模板

🌺函数模板的概念

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

🌺函数模板的格式

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

🌼示例1

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

🍁注意事项

  1. typename后面的内容不一定是T,可自由指定;
  2. typename是用来定义模板参数关键字,也可以使用class(切记:不能使用struct代替class);

🌼示例2

template<class N>
void Swap(N& a, N& b)
{
	auto tmp = a;
	a = b;
	b = tmp;
}

🌷函数模板的原理

函数模板是一个描述的过程一幅设计图一个模板,并不是真正的函数。编译器会根据模板使用特定方式产生具体类型函数。所以其实模板就是将本来应该我们做的重复的事情交给了编译器去做(想想印刷术的原理)。

C++——模板初阶与泛型编程

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

比如:当用double类型使用函数模板时,编译器通过对实参类型的推演,将T确定为double类型,然后产生一份专门处理double类型的代码,对于字符类型也是如此。

🌷函数模板的实例化

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

🌺隐式实例化

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

🌼示例1

template<class T>
T Add(T a, T b)
{
	return  a + b;
}
void Test()
{
	int a = 10;
	int b = 100;
	cout << Add(a, b) << endl;
}

C++——模板初阶与泛型编程

🌺显式实例化

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

🌼错误示例

template<class T>
T Add(T a, T b)
{
	return  a + b;
}

void Test()
{
	int a = 10;
	double d = 3.14;

	cout << Add(a, d) << endl;
}

🍁错误原因
因为在编译期间,当编译器看到该实例化时,需要推演其实参类型通过实参aT推演为int,通过实参dT推演为double类型,但模板参数列表中只有一个T,编译器无法确定此处到底该将T确定为int 或者 double类型而报错。

  • 在模板中,编译器一般不会进行类型转换操作。

C++——模板初阶与泛型编程
🌼正确的做法1

显式实例化:就是在告诉编译器:不用你推演了,我已经指定这个类型了。

template<class T>
T Add(T a, T b)
{
	return  a + b;
}

void Test()
{
	int a = 10;
	double d = 3.14;
	cout << Add<int>(a, d) << endl;
}

🌼正确的做法2

使用多个模板参数

template<class T,class Y>
Y Add(T a, Y b)
{
	return  a + b;
}

void Test()
{
	int a = 10;
	double d = 3.14;
	cout << Add<int>(a, d) << endl;
}

C++——模板初阶与泛型编程

🌺一个疑问

很多小伙伴初次理解模板都会有一个疑问——请问如下情况中,两次调用的swap函数是一个函数吗?或者说,两次调用的函数在同一个地址空间吗?

template<class N>
void Swap(N& a, N& b)
{
	auto tmp = a;
	a = b;
	b = tmp;
}
void Test()
{
	int a = 10;
	int b = 100;
	Swap(a,b);

	char c1 = 'a';
	char c2 = 'b';
	Swap(c1, c2);
}

我们不妨先来看看汇编代码吧。如下图所示,很显然两次调用的函数并不是一个函数(一个类型为Swap< int >,一个为Swap< char >)。事实上,虽然我们看不见这两份函数的代码,但是它们实实在在的产生了。
C++——模板初阶与泛型编程

🌷模板参数的匹配原则

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

🌼示例1

template<class T>
T Add(T a, T b)
{
	return  a + b;
}

int Add(int a, int b)
{
	return a + b;
}

void Test()
{
	int a = 10;
	int b = 100;
	cout << Add<int>(a, b) << endl;
}
  1. 对于非模板函数同名函数模板,如果其他条件都相同,在调动时会优先调用非模板函数而不会从该模板产生出一个实例。如果模板可以产生一个具有更好匹配的函数, 那么将选择模板

🌼示例2

template<class T,class Y>
Y Add(T a, Y b)
{
	cout << "模板" << endl;
	return  a + b;
}
int Add(int a, int b)
{
	cout << "非模板" << endl;
	return a + b;
}
void Test()
{
	int a = 10;
	int b = 100;
	double d = 3.14;
	cout << Add(a, b) << endl;//使用非模板函数
	cout << Add(a, d) << endl;//使用模板
}

C++——模板初阶与泛型编程

  1. 模板函数不允许自动类型转换,但普通函数可以进行自动类型转换(上文已提到,该情况可用多模板参数来解决)。

🌷类模板

同样的,对于也有同样的套路。

🌺类模板的定义格式

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

🌼示例

template<class T>
class Vector
{
public:
	//...
private:
	T* _a;
	size_t _size;
	size_t _capacity;
};

🌺类模板的实例化

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

🌼示例

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

C++——模板初阶与泛型编程

点击下方个人名片,可添加博主的个人QQ,交流会更方便哦~
↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓文章来源地址https://www.toymoban.com/news/detail-415884.html

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

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

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

相关文章

  • [C++]模板初阶与STL简介

    目录 模板初阶与STL简介::                                         1.泛型编程                                         2.函数模板                                         3.类模板                                         4.什么是STL                  

    2023年04月25日
    浏览(33)
  • 【C++】——模板(泛型编程+函数模板+类模板)

    之前我们学习了函数重载,让我们在写相似函数的时候非常方便,但函数重载还有很多不足的地方,比如,每次写相似函数的时候,都要我们重新重载一个逻辑、代码几乎一样的函数,这就导致了我们的效率变低,所以我们今天来学习C++模板的相关知识点,学习完模板之后,

    2024年02月05日
    浏览(46)
  • STL标准库与泛型编程(侯捷)笔记2

    本文是学习笔记,仅供个人学习使用。如有侵权,请联系删除。 参考链接 Youbute: 侯捷-STL标准库与泛型编程 B站: 侯捷 - STL Github:STL源码剖析中源码 https://github.com/SilverMaple/STLSourceCodeNote/tree/master Github:课程ppt和源码 https://github.com/ZachL1/Bilibili-plus 下面是第二讲的部分笔记:C++标

    2024年01月21日
    浏览(63)
  • STL标准库与泛型编程(侯捷)笔记4

    本文是学习笔记,仅供个人学习使用。如有侵权,请联系删除。 参考链接 Youbute: 侯捷-STL标准库与泛型编程 B站: 侯捷 - STL Github:STL源码剖析中源码 https://github.com/SilverMaple/STLSourceCodeNote/tree/master Github:课程ppt和源码 https://github.com/ZachL1/Bilibili-plus 介绍基于红黑树和hashtable的关联

    2024年01月21日
    浏览(58)
  • C++ 泛型编程:函数模板

    当需要编写通用的代码以处理不同类型的数据时,C++ 中的函数模板是一个很有用的工具。函数模板允许我们编写一个通用的函数定义,可以用于多种不同的数据类型,从而提高代码的重用性和灵活性。 泛型编程 是一种编程范式,旨在实现可重用、通用性高的代码。它允许我

    2024年02月12日
    浏览(41)
  • 【C++】泛型编程——模板进阶

    在之前的文章里,我们进行了模板初阶的学习( 【C++】泛型编程——模板初阶),了解了什么是泛型编程,学习了函数模板和类模板。 那这篇文章,我们继续学习模板进阶的内容的学习。 首先我们来回顾一下: 我们在模板初阶的学习中,定义模板参数是怎么定义的? 是不

    2024年02月16日
    浏览(34)
  • C++泛型编程之模板

    目录 一、什么是泛型编程  二、函数模板 2.1函数模板的概念 2.2函数模板格式 2.3函数模板的原理  2.5函数模板的实例化 2.6模板参数的匹配原则 三、类模板 3.1类模板的定义格式 3.2 类模板的实例化 四、非类型模板参数 五、模板的特化 5.1模板特化的概念: 5.2函数模板特化 5

    2024年02月07日
    浏览(38)
  • STL标准库与泛型编程(侯捷)笔记6(完结)

    本文是学习笔记,仅供个人学习使用。如有侵权,请联系删除。 参考链接 Youbute: 侯捷-STL标准库与泛型编程 B站: 侯捷 - STL Github:STL源码剖析中源码 https://github.com/SilverMaple/STLSourceCodeNote/tree/master Github:课程ppt和源码 https://github.com/ZachL1/Bilibili-plus 下面是C++标准库体系结构与内核

    2024年01月16日
    浏览(51)
  • 【C++】泛型编程 ② ( 函数模板与普通函数区别 )

    函数模板与普通函数区别 : 主要区别在于它们能够处理的 数据类型数量 和 灵活性 ; 自动类型转换 : 函数模板 不允许 自动类型转化 , 会进行严格的类型匹配 ; 普通函数 能够进行 自动类型转换 , 内含隐式的类型转化 ; 参数 / 返回值 数据类型 : 普通函数 只接受 特定类型 参数

    2024年02月20日
    浏览(36)
  • 【C++】泛型编程 ③ ( 函数模板 与 普通函数 调用规则 | 类型匹配 | 显式指定函数模板泛型类型 )

    上一篇博客 【C++】泛型编程 ② ( 函数模板与普通函数区别 ) 中 , 分析了 函数参数 类型匹配 下的 普通函数 与 函数模板 的调用规则 ; 为 函数模板 重载了 普通函数 , 普通函数有指定的类型 ; 传入实参 , 调用 普通函数 还是 模板函数 , 是有一定的规则的 ; 普通函数 与 传入实

    2024年02月21日
    浏览(42)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包