C++模板的特化(specialization)和偏特化(partial specialization)

2023-11-07

模板函数和模板类有的时候可能需要对传入的不同类型进行不同的处理,比如说有的模板传入int或double类型都可以处理,但是传入char型则会出错,这时就需要模板特化的方式。

类模板全特化:

全特化即将模板类型里的所有类型参数全部具体指明之后处理,如下

template<typename T,typename C>
struct A
{
    A(){cout<<"泛化版本构造函数"<<endl;}
    void func()
    {
        cout<<"泛化版本"<<endl;    
    }
};
 
template<>
struct A<int,int>
{
   A(){cout<<"int,int特化版本构造函数"<<endl;}
   void func()
   {
       cout<<"int,int特化版本"<<endl;    
   } 
};
 
template<>
struct A<double,double>
{
   A(){cout<<"double,double特化版本构造函数"<<endl;}
   void func()
   {
       cout<<"double,double特化版本"<<endl;    
   } 
};


int main()
{
    A<int,double> a;//调用泛化构造函数
    a.func();//调用泛化版本函数
    A<int,int> a;//调用int,int特化构造函数
    a.func();//调用int,int特化版本函数
    A<double,double> a;//调用double,double特化构造函数
    a.func();//调用double,double特化版本函数
}

template<>中为空,代表所有类型都在下面特殊化处理,上面相当于对int,int和double,double两种类型进行了分别的处理,其他类型依然是泛化版本。

对类中的某个成员函数进行特化处理

还是以上面给的例子为基础,特化func()成员函数,当A的模板参数为<int,double>时,调用特化版的func()。

template<>
void A<int,double>::func
{
    cout<<"int,double特化版本函数"<<endl;
}
 
int main()
{
    A<int,double> a;//调用泛化版本构造函数
    a.func();//调用int,double特化版本函数
}

类模板的偏特化

类模板偏特化(局部特化):顾名思义,只特殊化几个参数或者一定的参数范围

个数偏特化

template<typename T,typename C,typename D>
struct A
{
	void func()
	{
		cout << "泛化版本" << endl;
	}
};
 
template<typename C>
struct A<int,C,int>
{
	void func()
	{
		cout << "int,C,int偏特化版本" << endl;
	}
};
 
template<typename C>
struct A<double, C, double>
{
	void func()
	{
		cout << "double,C,double偏特化版本" << endl;
	}
};
int main()
{
	A<double, int, int> a;
	a.func();//调用泛化版本
	A<int, char, int> b;
	b.func();//调用int,C,int偏特化版本
	A<double, int, double> c;
	c.func();//调用double,C,double偏特化版本
}

template<>括号中存留的参数是依然可以任意填的参数。

STL中的一个个数偏特化例子
在这里插入图片描述

范围偏特化

注意范围二字,比如const int属于int的一个小范围,int *和const int*属于int的一个小范围,int&属于int的一个小范围,int&&属于int的一个小范围

template<typename T>
struct A
{
	void func()
	{
		cout << "泛化版本" << endl;
	}
};
 
template<typename T>
struct A<const T>
{
	void func()
	{
		cout << "const T版本" << endl;
	}
};
 
template<typename T>
struct A<T*>
{
	void func()
	{
		cout << "T*版本" << endl;
	}
};
 
template<typename T>
struct A<T&>
{
	void func()
	{
		cout << "T&版本" << endl;
	}
};
 
template<typename T>
struct A<T&&>
{
	void func()
	{
		cout << "T&&版本" << endl;
	}
};
int main()
{
	A<int> a;
	a.func();
	A<const int> b;
	b.func();
	A<int *> c;
	c.func();
	A<const int *> d;
	d.func();
	A<int&> e;
	e.func();
	A<int&&> f;
	f.func();
}

在这里插入图片描述

记住这种情况的template<>中还是要填上原有的大类型,且const T*属于T*不属于const T

STL中的一个范围偏特化例子
在这里插入图片描述

函数模板全特化:

template<typename T,typename C>
void func(T &a, C &b)
{
	cout << "------------------------" << endl;
	cout << "泛化版本" << endl;
	cout << a << endl;
	cout << b << endl;
	cout << "------------------------" << endl;
}
 
template<>
void func(int &a, int &b)
{
	cout << "------------------------" << endl;
	cout << "int,int特化版本" << endl;
	cout << a << endl;
	cout << b << endl;
	cout << "------------------------" << endl;
}
 
 
int main()
{
	double a = 1.0;
	double b = 2.0;
	func(a, b);
	int c = 3;
	int d = 4;
	func(c, d);
}

在这里插入图片描述

假如说存在非模板的重载函数,且其与特化的一个版本一样

,如下所示:
template<typename T,typename C>
void func(T &a, C &b)
{
	cout << "------------------------" << endl;
	cout << "泛化版本" << endl;
	cout << a << endl;
	cout << b << endl;
	cout << "------------------------" << endl;
}
 
template<>
void func(int &a, int &b)
{
	cout << "------------------------" << endl;
	cout << "int,int特化版本" << endl;
	cout << a << endl;
	cout << b << endl;
	cout << "------------------------" << endl;
}
 
void func(int &a, int &b)
{
	cout << "------------------------" << endl;
	cout << "重载版本" << endl;
	cout << a << endl;
	cout << b << endl;
	cout << "------------------------" << endl;
}
int main()
{
	double a = 1.0;
	double b = 2.0;
	func(a, b);
	int c = 3;
	int d = 4;
	func(c, d);
	int e = 3;
	int f = 4;
	func<int, int>(e, f);
}

在这里插入图片描述
则在你不特地指明参数类型时,编译器会优先选择重载普通函数版本。

函数模板偏特化:

函数模板不能偏特化!!!!!!!!!!!!!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++模板的特化(specialization)和偏特化(partial specialization) 的相关文章

随机推荐

  • 【Hexo】【Blog】更换主题【简】

    下载 Hexo themes Github NEXT主题 新建文件夹 这里想偷个懒一次装好 需要安装一些插件工具 有些小头疼 还是从GitHub拉下来再去改个性化的界面吧 ps 用git拉下来的话也比较慢 如果不换源的话 我依旧down下来
  • 解密Kerberos流量

    以下主要演示如何通过将keytab导入到wireshark 实现对Kerberos协议进行解密 Keytab 那么Keytab是什么 keytab是可以理解为一个密钥表 是key table的缩写 用途类似于用户的密码 keytab中包含一
  • Docker实战:docker compose 搭建Rocketmq

    1 配置文件准备 1 1 新建目录 home docker data rocketmq conf mkdir home docker data rocketmq conf 1 2 在上面目录下新建文件broker conf文件 内容如下 b
  • JSX的基础使用(二)

    1 事件绑定 React 事件的 命名采用小驼峰式 camelCase 而不是纯小写 们需要 通过 传入一个事件处理函数 这个函数会在事件发生时被执行 2 this绑定 bind给btnClick显示绑定this 使用 ES6 class
  • 面向过程编程

    p 面向过程编程 p p p
  • Qt 使用中文引起的错误error: C2001: 常量中有换行符;error: C1071: 在注释中遇到意外的文件结束

    中文编码问题导致的错误 解决办法 1 使用英文注释 2 在中文的结尾加上英文 或者空格 3 修改设置 编辑 gt 选择编码 gt system gt 编码保存
  • 六、Audio-ALSA架构中的codec

    一 codec简介 处理器如果既想 听到 外界的声音 又想向外界传达自己的 心声 那么就需要同时用到 DAC 和 ADC 这两款芯片 那是不是买两颗 DAC 和 ADC 芯片就行了呢 答案肯定是可以的 但是音频不单单是能出声 能听到就行 我
  • VC6 ”add files to project“功能失效的解决方案

    在Win7系统下 安装MS2007以后 VC6 0 add files to project 功能失效了 网上的资料表明 这是与MS2007不兼容导致的 其具体解决方案如下 1 到如下网址 http download microsoft c
  • 服务器硬件规格常用查看命令——磁盘相关命令

    smartctl smartctl是一个能够控制和监控磁盘的SMART Self Monitoring Analysis and Reporting Technology 自我监测 分析和报告技术 命令 使用方法 提示 使用该命令只能查看到
  • Apache Hop-使用介绍【持续完善中】

    文章目录 Pipelines 管道 Pipeline Editor 管道编辑器 TOOLBAR Create a Pipeline 创建管道 How pipelines work 管道如何工作 Concepts 概念 Create a pi
  • 计算机组成原理(七)——总线BUS

    总线 BUS 总线 BUS 概念 连接计算机系统各个功能部件的信息传输线 是各个部件共享数据及信息的传输介质 用来连接计算机系统各功能部件而构成一个完整系统 实际上是一组信号线 广义地讲 任何连接两个以上电子元器件的导线都可以称为总线 计算
  • 微服务系列文章之 Redisson实现分布式锁

    一 高效分布式锁 当我们在设计分布式锁的时候 我们应该考虑分布式锁至少要满足的一些条件 同时考虑如何高效的设计分布式锁 这里我认为以下几点是必须要考虑的 1 互斥 在分布式高并发的条件下 我们最需要保证 同一时刻只能有一个线程获得锁 这是最
  • 【go】异步任务解决方案Asynq实战

    文章目录 一 Asynq介绍 二 所需工具 三 代码示例 四 Reference 一 Asynq介绍 Asynq 是一个 Go 库 一个高效的分布式任务队列 Asynq 工作原理 客户端 生产者 将任务放入队列 服务器 消费者 从队列中拉出
  • openEuler之RPM软件包管理命令

    RPM命令介绍 安装软件 rpm i xx rpm 卸载软件 rpm e xx rpm 升级形式安装 rpm U xx rpm 常用参数 v 显示详细信息 h 显示文本进度条 1 安装软件 1 下载RPM包 root localhost l
  • K8s企业版多节部署

    K8s企业版多节部署 实验步骤 K8s的单节点部署 master2节点部署 负载均衡部署 使用双机热备 k8s网站页面 实验环境 使用Nginx做负载均衡 lb01 192 168 217 136 24 CentOS 7 5 lb02 19
  • DLL+资源模块切换

    MFC程序中存在一个模块状态 Module State 的问题 也就是资源重复的问题 此处的术语模块是指一个可执行程序 或指其操作不依赖于应用程序的其余部分但使用MFC运行库的共享副本的一个DLL 或一组DLL 我们所创建的MFC DLL就
  • VS2019配置opencv详细图文教程和测试代码

    摘要 vs2019新鲜出炉 配置opencv又有哪些不一样呢 这个教程将会一步一步的教你如何配置opencv和跑动opencv一个简单的项目 测试代码请在原文找到 转发备注原文链接 https xygeng cn post 151 html
  • 机器学习数据获取与处理

    数据获取与处理 以CV任务为主 课程目的 数据的获取途径 数据处理与标注 数据预处理方法 模型训练评估 一 数据集的获取 通常 我们的数据来源于各个比赛平台 首先是AIStudio中的数据集 大部分经典数据集例如百度AI Studio Ka
  • 小程序用户隐私保护协议纯文案修改指引

    目录 一 修改缘由 二 官方指引 三 填写入口 一 修改缘由 小程序提交审核不通过 审核失败原因 存在平台未允许的服务内容 违反 微信小程序平台运营规范常见拒绝情形3 4 详情描述 你好 你的小程序涉及收集 使用和存储用户信息 请增加 用户
  • C++模板的特化(specialization)和偏特化(partial specialization)

    C 模板的特化及偏特化 类模板全特化 对类中的某个成员函数进行特化处理 类模板的偏特化 个数偏特化 范围偏特化 函数模板全特化 函数模板偏特化 模板函数和模板类有的时候可能需要对传入的不同类型进行不同的处理 比如说有的模板传入int或dou