IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++模板进阶 -> 正文阅读

[C++知识库]C++模板进阶

●🧑个人主页:你帅你先说.
●📃欢迎点赞👍关注💡收藏💖
●📖既选择了远方,便只顾风雨兼程。
●🤟欢迎大家有问题随时私信我!
●🧐版权:本文由[你帅你先说.]原创,CSDN首发,侵权必究。

🍉1.非类型模板参数

模板参数分为类型形参非类型形参
类型形参即出现在模板参数列表中,跟在class或者typename之类的参数类型名称。
非类型形即用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当成常量来使用。

非类型模板参数有什么用呢?比如我们自己写一个可以控制大小的栈,我们希望每次定义栈可以根据需求来定义不同大小的栈,有的人会想用宏定义,去改对应的值就行,但这样每次换一个大小就要改一次未免太麻烦了,所以就有了非模板参数。

// 非类型模板参数 -- 必须是整型常量
template<class T, size_t N = 10>
class MyStack
{
public:
	void Push(const T& x)
	{}
private:
	T _a[N];
	size_t _top;
int main()
{
	MyStack<int,100> st1;
	MyStack<int,200> st2;
};

??注意:

  • 浮点数、类对象以及字符串是不允许作为非类型模板参数的。
  • 非类型的模板参数必须在编译期就能确认结果。

🍊2.类模板的特化

// 特化 -- 特殊化,比如需要针对某些类型特殊化处理
template<>
struct Less<Date*>
{
	bool operator()(Date* x,Date* y) const
	{
		return *x < *y;
	}
};
int main()
{
	priority_queue<Date*> pq;
	//优先使用特化的模板
	pq.push(new Date(2022, 3, 26));
	pq.push(new Date(2021, 10, 26));
	pq.push(new Date(2023, 3, 26));

	while (!pq.empty())
	{
		cout << *pq.top();
		pq.pop();
	}
	cout << endl;

	return 0;
}

特化与缺省值类似,分为全特化和半特化。半特化一般我们称为偏特化。
?全特化
全特化即是将模板参数列表中所有的参数都确定化。

template<>
class Data<int, char> 
{
public:
 	Data() {cout<<"Data<int, char>" <<endl;}
private:
	 int _d1;
	 char _d2;
};

?偏特化
偏特化:任何针对模版参数进一步进行条件限制设计的特化版本。

template <class T1>
class Data<T1, int>
{
public:
 	Data() {cout<<"Data<T1, int>" <<endl;}
private:
	 T1 _d1;
	 int _d2;
};
//这种情况很容易误认为是普通的类模板。
template <class T1,class T2>
class Data<T1*, T2*>
{
public:
 	Data() {cout<<"Data<T1, int>" <<endl;}
private:
	 T1 _d1;
	 T2 _d2;
};

🍋3.模板的分离编译

🍎3.1 什么是分离编译

一个程序(项目)由若干个源文件共同实现,而每个源文件单独编译生成目标文件,最后将所有目标文件链接起来形成单一的可执行文件的过程称为分离编译模式

在这里插入图片描述
比如我们在学数据结构时手写一个栈,这个时候我们就会把函数的各种声明放在.h文件里,而定义放在.cpp文件里,让声明和定义分离,这就是分离编译。

🍎3.2 模板的分离编译

在C++里,模板是不支持分离编译的。为什么?
我们知道,执行一个程序是要经历一下几个过程的。
预处理:头文件展开、条件编译、宏替换、去掉注释。
编译:检查语法问题,生成汇编代码
汇编:,生成符号表,把汇编代码转换成二进制机器码
链接:合并段表,符号表的定位和重定向。

首先,一般我们写一个项目会有.h.cpptest.cpp这三个文件,一般声明放在.h,定义放在.cpp,test用来测试程序,主函数也是写在测试里。
在这个过程中编译器不会去编译.cpp里的函数模板,因为没有实例化,编译器没法生成具体的函数,也就是不会生成汇编代码,这个函数也不会生成地址。在链接之前,这三个文件编译产生的新文件是不会有交互的,在链接时编译器找不到这个函数模板的地址,因此在链接时报错。而如果定义在一个文件里,在链接之前模板就可以进行实例化,函数模板也就有了地址,这样在链接时就不会存在找不到函数地址的问题。

🥝4.模板总结

??函数模板和模板函数的区别
函数模板提供了一类函数的抽象,它提供了任意类型为参数及返回值,而模板函数是函数模板经实例化后生成的具体函数,所以函数模板代表了一类函数,模板函数表示某个具体函数。
类模板和模板类和上述同理,我们STL中学的vector< int >、stack< int >等就是模板类。
【优点】
1. 模板复用了代码,节省资源,更快的迭代开发,C++的标准模板库(STL)因此而产生
2. 增强了代码的灵活性

【缺陷】
1. 模板会导致代码膨胀问题,也会导致编译时间变长
3. 出现模板编译错误时,错误信息非常凌乱,不易定位错误

请添加图片描述
喜欢这篇文章的可以给个一键三连 点赞👍关注💡收藏💖

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-01 23:08:08  更:2022-04-01 23:09:41 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:38:22-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码