代码编织梦想

🧸🧸🧸各位大佬大家好,我是猪皮兄弟🧸🧸🧸
在这里插入图片描述

一、模板参数

模板参数分为类型形参与非类型形参
类型形参:出现在模板参数中,跟在class或者typename之后的参数类型名称
非类型形参:就是一个常量作为类模板/函数模板的一个参数,在类模板/函数模板中可将该参数当成常量来使用

1.非类型模板参数

template<class T,size_t N=100>//缺省参数
class Array
{
private:
	T _a[N];
}

需要注意的是:浮点数、类对象以及字符串是不允许作为非类型参数的。也就是说,非类型模板参数只允许是整形家族(char类型也算在整形家族),而且非类型模板参数是在编译阶段就要能确定。

比如库中的array

库中的array

template<class T,size_t N> class array;

2.类型模板参数

这个就简单提一下吧,平时正常用的就是这个

template<class T>
class Node
{
	//...
private:
	T data;
	Node<T> *_next;
}

二、模板参数的特化

特化就是特殊化
通常情况下,使用模板可以处理一些类型无关的代码,但对一些类型可能会得到一些错误的结果,需要特殊处理,比如:我想实现一个进行小于比较的函数模板,但是对于某些类型,它的行为不是我想要的,针对某些类型进行特殊化处理

template<class T>
bool Greater(T left,T right)
{
	return left>right;
}
template<>
bool Greater(Date* left,Date* right)//是一个日期类
{
	return *left>*right;//日期类中重载了operator>
}

再比如后面学哈希的时候,一些哈希函数处理某些类型也需要用到特化,比如哈希函数处理字符串。

特化不能单独使用,特化必须是对已有的模板进行特化。
有特化就用特化,没有编译器就会去按模板推演实例化出新的

1.全特化

template <class T1,class T2>
class Date
{
  ....  
};
template<>
class Date<int,char>
{
    ....
}

2.偏特化(半特化)

template<class T1,class T2>
class Date
{
    ....
}
template<class T1>
class Date<T1,int>
{
    ...
}
template<class T1,class T2>
class Date<T1*,T2*>//这也是偏特化
{
    ...
}
template<class T1,class T2>
class Date<T1&,T2&>//这也是偏特化
{
    ....
}

三、模板的分离编译的问题

分离编译是指的,模板的声明放在头文件,定义放在源文件

1.模板的分离编译书写很麻烦

比如现在我分离编译了模拟实现的vector

//定义的时候
template<class T>
typename vector<T>::iterator vector<T>::insert(typename vector<T>::iterator pos,const T&x)
{
	//...
}

这是遇到的模板中typename和class的第一个区别,这里是因为vector::成员,它不知道你要去访问静态成员还是iterator这个类型。加上typename就是为了告诉编译器vector::iterator是一个类型,不然的化就有二义性,因为静态成员也是这样访问的

2.模板的分离编译有声明但找不到定义

解释:生成目标文件之前,头文件的内容早在预编译阶段就被展开到了源文件当中,但是其他的都能链接的上,唯独模板分离编译的链接不上,原因就是模板分离编译的东西没有被实例化(链接之前,多个源文件并不会交汇,比如说我有vector.hpp vector.cpp和test.cpp,test.cpp和vetcor.cpp包含头文件vector.hpp,预编译阶段,vector.hpp展开到了两个源文件当中。但是在编译阶段,在vector.i中并不会去对模板进行编译,因为没有人告诉他准确的T类型)所以在链接阶段链接的时候,只有声明没有定义,链接的时候去符号表中找,找不到,链接错误,问题就出在编译阶段没有被实例化

所以提倡模板声明和定义不分离(分离是指的在两个文件当中,因为两个源文件不会交互,模板的准确类型得不到),小函数应该放在类中称为内联,大函数应该在类外定义,因为类里只有声明的话就可以更好的看到整个的框架

3.模板分离编译的解决办法

解决办法就是显示实例化,但是显示实例化时把类型写死了,所以非常不推荐

//在分离编译的地方给给定义
template
vector<int>;

template
vector<double>;

显示实例化可以有多个

四、模板总结

优点

1.模板服用了代码,节省资源,更快的迭代开发,C++标准模板库因此而产生
2.增强代码的灵活性,重复的事情交给 编译器做

缺点

1.模板会导致代码膨胀问题(inline之所以是建议性关键字的问题也是内联会代码碰撞),也会导致编译时间变长
2.出现模板编译错误时,错误信息非常凌乱,不易定位错误

在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zhu_pi_xx/article/details/128008587

【C++】模板进阶-爱代码爱编程

模板进阶 1.非类型模板参数2. 模板的特化2.1 函数模板特化2.2 类模板特化2.2.1 全特化2.2.2 偏特化2.3 类模板特化应用之类型萃取3. 模板分离编译3.1 什么是分离编译3.1.1 不含模板代码的分离编译3.1.2 含有模板代码的分离编译3.2 问题解决方法4. 模板总结 1.非类型模板参数 类型模板参数:出现在模板参数列

模板进阶-爱代码爱编程

目录 非类型模板参数模板的特化概念函数模板特化类模板特化全特化偏特化模板分离编译概念模板的分离编译解决办法 非类型模板参数 类类型形参:出现在模板参数列表中,跟在class或者typename之后的参数类型名称;非类型形参:就是用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当成常量来使用;// 定义一个模板类型的静态数组

C++模板进阶操作 —— 非类型模板参数、模板的特化以及模板的分离编译-爱代码爱编程

文章目录 非类型模板参数模板的特化概念函数模板特化类模板特化全特化偏特化模板的分离编译什么是分离编译模板的分离编译解决方法模板总结 非类型模板参数 模板参数可分为类型形参和非类型形参。类型形参: 出现在模板参数列表中,跟在class或typename关键字之后的参数类型名称。非类型形参: 用一个常量作为类(函数)模板的一个参数,在类(函数)模

C++之模板进阶-爱代码爱编程

模板进阶 文章目录 模板进阶非类型模板参数非类型模板参数缺省值模板的特化概念函数模板的特化类模板的特化全特化偏特化模板分离编译什么是分离编译模板总结优点缺点 没了解过模板的读者,先学习模板初阶: C++之模板初阶 通过模板我们可以实现泛型编程,模板分为函数模板和类模板,下面我们就说点模板进阶的一些东西。 非类型模板参数 模板参数分类类型

C++模板进阶-爱代码爱编程

文章目录 一、非类型模板参数二、模板的特化2.1 引入特化2.2 函数模板的特化2.3 类模板特化2.3.1 偏特化2.3.2 全特化三、模板分离编译 一、非类型模板参数 模板参数分为类型形参与非类型形参。 类型形参即:出现在模板参数列表中,跟在class或者typename之类的参数类型名称。非类型形参,就是用一个常量作为类(函数)模板的

C++初阶:模板进阶-爱代码爱编程

泛型编程和模板 STL 简介 STL(standard template libaray)是 C++ 标准库的重要组成部分:标准模板库。STL 不仅是一个可复用的组件库,而且 是一个包罗数据结构与算法的软件框架。 原始版本 Alexander Stepanov、Meng Lee 在惠普实验室完成的原始版本,本着开源精神,他们声明允许任何人任意运用、拷

C++初阶:初识模板和泛型编程-爱代码爱编程

初识模板 1. 模板初阶 1.1 泛型编程 void Swap(int& left, int& right) { // 交换两个整型变量 int tmp = left; left = right; right = tmp; } void Swap(double& left, double& right) { //

C++ 模板进阶-爱代码爱编程

目录 1.非类型模板参数 2.类模板的特化 2.1 概念  2.2 函数模板特化 2.3类模板特化   2.3.1 全特化 2.3.2 偏特化 3.类模板特化的应用之类型萃取 3.1 什么是分离编译 3.2 模板的分离编译  3.3 解决方法 4.模板的分离编译 1.非类型模板参数 模板参数分类类型形参与非类型

c++ 模板进阶篇_爱编程的小李同学的博客-爱代码爱编程

C++ 模板进阶篇 一、非类型模板参数二、模板的特化1、特化概念2、函数模板特化3、类模板特化3.1 全特化3.2 偏特化3.3 类模板特化应用示例三、模板分离编译1、分离编译概念2、模板的分离编译3、解决方法总结 一、非类型模板参数 在模板中,模板参数分类型形参与非类型形参。 类型形参:出现在模板参数列表中,跟在class或者typena

c++ 【模版进阶】模版分离编译 模版特化_酬 勤的博客-爱代码爱编程

文章目录 非类型模板参数类模板的特化函数模板特化 类模板特化全特化全特化的应用场景偏特化 模板分离编译什么是分离编译模板的分离编译模板总结 非类型模板参数 模板参数分类类型形参与非类型形

[ c++ ] template 模板进阶 (特化,分离编译)_小白又菜的博客-爱代码爱编程

本篇内容包括C++ 非典型模板参数,类模板的特化,模板的分离编译。C++模板简单概念及其使用大家可点击此链接:[ C++ ] C++之模板template 目录 1.  数组模板示例和非类型模板参数 2.模板的特化 2.1什么是模板的特化 2.2 函数模板特化 2.3 类模板特化  2.3.1 全特化 2.3.2 偏特化 3.

【初阶与进阶c++详解】第十二篇:模板进阶(函数模板特化+类模板特化+模板分离编译)_企鹅不叫的博客-爱代码爱编程

🏆个人主页:企鹅不叫的博客 ​ 🌈专栏 C语言初阶和进阶C项目Leetcode刷题初阶数据结构与算法C++初阶和进阶《深入理解计算机操作系统》《高质量C/C++编程》Linux ⭐️ 博主码云gitee链接

c/c++编译器配置——mingw下载安装_cilinx的博客-爱代码爱编程

一. 前言 由于重装Win11系统,所有配置环境需要重装,对于C/C++编译器MinGW配置做一个简单记录。 VS code等软件只提供编辑器,不提供编译器,因此windows系统上的C/C++编译器需要通过安装MinGW

剖分(树形差分)_wyw___的博客-爱代码爱编程

E-剖分_牛客小白月赛62 (nowcoder.com) 题目描述 牛牛有一颗包含n个结点的二叉树,这些结点编号为1 ...n。这颗树被定义为:1、以结点1为根。 2、编号为α结点的两个儿子编号分别为:2 xa和2×巴+ 1。3、每个结点的权重初始都为0。 牛牛接下来会对这颗树进行m次操作,操作的格式是以下四种之—: 1、op a(这里op = 1)代表

【c++】模板进阶 —— 非类型模板参数 | 特化 | 模板的分离编译-爱代码爱编程

模板进阶 1. 非类型模板参数2. 模板的特化2.1 函数模板的特化2.2 类模板的特化2.2.1 全特化2.2.2 偏特化 3. 模板的分离编译4. 模板总结 反爬链接 正文开始

【c++】模板进阶 — 模板特化-爱代码爱编程

文章目录 📖前言1. typename的深一层应用2. 非类型模板参数2.1 非类型模板参数的引入:2.2 array的特性和使用: 3. 模板的特化3.1 模板的特化的引入 + 函数模板的特化: