什么是C++中的模板特化和偏特化?

news2024/11/24 12:31:13

C++中的模板特化和偏特化是模板编程中的重要概念,它们允许程序员为特定类型或条件提供更具体的实现。

模板特化

模板特化是指为特定类型提供一个明确的实现,从而覆盖普通模板的通用实现。这通常在模板类或函数对某个特定类型的处理方式需要不同于一般类型时使用。

完全特化

完全特化是指模板的所有参数都被固定为具体类型。

语法:

template <typename T>  
class MyClass {  
public:  
    void func() {  
        // 默认实现  
    }  
};  

// 完全特化  
template <>  
class MyClass<int> {  
public:  
    void func() {  
        // 针对 int 的特化实现  
    }  
};

示例:

#include <iostream>  

// 通用模板  
template <typename T>  
class Printer {  
public:  
    void print(T value) {  
        std::cout << "Value: " << value << std::endl;  
    }  
};  

// 对 int 类型的完全特化  
template <>  
class Printer<int> {  
public:  
    void print(int value) {  
        std::cout << "Integer: " << value << std::endl;  
    }  
};  

int main() {  
    Printer<double> p1;  
    p1.print(5.5); // 输出: Value: 5.5  

    Printer<int> p2;  
    p2.print(5); // 输出: Integer: 5  

    return 0;  
}


输出:

     Value: 5.5
     Integer: 5

在这个例子中,Printer<int> 是对 Printer<T> 的完全特化,用于处理 int 类型。

偏特化

模板偏特化是指只针对模板的某些参数进行特化,而其他参数保持为模板类型。这通常用于处理有多个参数的模板类更多样化和灵活性。

语法:

template <typename T, typename U>  
class MyClass {  
public:  
    void func() {  
        // 默认实现  
    }  
};  

// 偏特化  
template <typename T>  
class MyClass<T, int> {  
public:  
    void func() {  
        // 针对第二个参数为 int 的特化实现  
    }  
};

示例: 

#include <iostream>  

// 通用模板  
template <typename T, typename U>  
class Pair {  
public:  
    void show() {  
        std::cout << "Generic Pair" << std::endl;  
    }  
};  

// 对第二个参数为 int 的偏特化  
template <typename T>  
class Pair<T, int> {  
public:  
    void show() {  
        std::cout << "Pair with second type as int" << std::endl;  
    }  
};  

int main() {  
    Pair<double, double> p1;  
    p1.show(); // 输出: Generic Pair  

    Pair<double, int> p2;  
    p2.show(); // 输出: Pair with second type as int  

    return 0;  
}

//输出:
        Generic Pair
        Pair with second type as int

在这个例子中,Pair<T, int> 是对 Pair<T, U> 的偏特化,仅当第二个模板参数为 int 时使用。

范围特化

在 C++ 中,“范围特化”(通常被称为“部分特化”或“范围特化”)并不是一个官方术语,它通常指的是通过对模板参数使用某种范围条件、特定类型或组合条件来定义特化模板。这有点类似于部分特化,但更具体于使用特定的特化条件。

数字范围特化

假设我们希望实现一个函数模板,可以处理不同的数值类型并对其范围进行特化。

#include <iostream>  
#include <type_traits>  

// 通用模板  
template <typename T>  
void display(T value) {  
    std::cout << "Generic value: " << value << std::endl;  
}  

// 特化:当 T 是整数类型  
template <typename T>  
void display(T value) {  
    static_assert(std::is_integral<T>::value, "Only integral types are allowed.");  
    std::cout << "Integer value: " << value << std::endl;  
}  

// 特化:当 T 是浮点类型  
template <typename T>  
void display(T value) {  
    static_assert(std::is_floating_point<T>::value, "Only floating point types are allowed.");  
    std::cout << "Float value: " << value << std::endl;  
}  

int main() {  
    display(10);       // 输出: Integer value: 10  
    display(3.14);    // 输出: Float value: 3.14  
    // display("Hello"); // 会导致编译错误  

    return 0;  
}

在这个例子中,使用 std::is_integral 和 std::is_floating_point 检查类型的范围,并为不同的数据类型提供不同的实现。

模板部分特化
#include <iostream>  

// 通用模板类  
template <typename T, typename U>  
class Pair {  
public:  
    void show() {  
        std::cout << "Generic Pair" << std::endl;  
    }  
};  

// 偏特化:当第二个参数是 int  
template <typename T>  
class Pair<T, int> {  
public:  
    void show() {  
        std::cout << "Pair with second type as int" << std::endl;  
    }  
};  

// 偏特化:当第二个参数是 double  
template <typename T>  
class Pair<T, double> {  
public:  
    void show() {  
        std::cout << "Pair with second type as double" << std::endl;  
    }  
};  

int main() {  
    Pair<double, int> p1;  
    p1.show(); // 输出: Pair with second type as int  

    Pair<int, double> p2;  
    p2.show(); // 输出: Pair with second type as double  

    Pair<int, int> p3;  
    p3.show(); // 输出: Generic Pair  

    return 0;  
}

在这个例子中,根据第二个模板参数的类型(int 和 double),对 Pair 类进行了特化。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2246657.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言--分支循环编程题目

第一道题目&#xff1a; #include <stdio.h>int main() {//分析&#xff1a;//1.连续读取int a 0;int b 0;int c 0;while (scanf("%d %d %d\n", &a, &b, &c) ! EOF){//2.对三角形的判断//a b c 等边三角形 其中两个相等 等腰三角形 其余情…

Linux——用户级缓存区及模拟实现fopen、fweite、fclose

linux基础io重定向-CSDN博客 文章目录 目录 文章目录 什么是缓冲区 为什么要有缓冲区 二、编写自己的fopen、fwrite、fclose 1.引入函数 2、引入FILE 3.模拟封装 1、fopen 2、fwrite 3、fclose 4、fflush 总结 前言 用快递站讲述缓冲区 收件区&#xff08;类比输…

git(Linux)

1.git 三板斧 基本准备工作&#xff1a; 把远端仓库拉拉取到本地了 .git --> 本地仓库 git在提交的时候&#xff0c;只会提交变化的部分 就可以在当前目录下新增代码了 test.c 并没有被仓库管理起来 怎么添加&#xff1f; 1.1 git add test.c 也不算完全添加到仓库里面&…

GESP2023年9月认证C++四级( 第三部分编程题(1-2))

编程题1&#xff08;string&#xff09;参考程序&#xff1a; #include <iostream> using namespace std; long long hex10(string num,int b) {//int i;long long res0;for(i0;i<num.size();i) if(num[i]>0&&num[i]<9)resres*bnum[i]-0;else //如果nu…

Ultiverse 和web3新玩法?AI和GameFi的结合是怎样

Gamef 和 AI 是我们这个周期十分看好两大赛道之一&#xff0c;(Gamef 拥有极强的破圈效应&#xff0c;引领 Web2 用户进军 Web3 最佳利器。AI是这个周期最热门赛道&#xff0c;无论 Web2的 OpenAl&#xff0c;还是 Web3&#xff0c;都成为话题热议焦点。那么结合 GamefiA1双叙事…

如何在 UniApp 中实现 iOS 版本更新检测

随着移动应用的不断发展&#xff0c;保持应用程序的更新是必不可少的&#xff0c;这样用户才能获得更好的体验。本文将帮助你在 UniApp 中实现 iOS 版的版本更新检测和提示&#xff0c;适合刚入行的小白。我们将分步骤进行说明&#xff0c;每一步所需的代码及其解释都会一一列出…

解决 npm xxx was blocked, reason: xx bad guy, steal env and delete files

问题复现 今天一位朋友说&#xff0c;vue2的老项目安装不老依赖&#xff0c;报错内容如下&#xff1a; npm install 451 Unavailable For Legal Reasons - GET https://registry.npmmirror.com/vab-count - [UNAVAILABLE_FOR_LEGAL_REASONS] vab-count was blocked, reas…

【AI系统】GPU 架构回顾(从2018年-2024年)

Turing 架构 2018 年 Turing 图灵架构发布&#xff0c;采用 TSMC 12 nm 工艺&#xff0c;总共 18.6 亿个晶体管。在 PC 游戏、专业图形应用程序和深度学习推理方面&#xff0c;效率和性能都取得了重大进步。相比上一代 Volta 架构主要更新了 Tensor Core&#xff08;专门为执行…

每天五分钟机器学习:支持向量机数学基础之超平面分离定理

本文重点 超平面分离定理(Separating Hyperplane Theorem)是数学和机器学习领域中的一个重要概念,特别是在凸集理论和最优化理论中有着广泛的应用。该定理表明,在特定的条件下,两个不相交的凸集总可以用一个超平面进行分离。 定义与表述 超平面分离定理(Separating Hy…

docker镜像源配置、换源、dockerhub国内镜像最新可用加速源(仓库)

一、临时拉取方式 在docker pull后先拼接镜像源域名&#xff0c;后面拼接拉取的镜像名 $ docker pull dockerpull.org/continuumio/miniconda3 二、永久配置方式 vim修改/etc/docker/daemon.json&#xff0c;并重启docker服务。 # 创建目录 sudo mkdir -p /etc/docker# 写…

电脑使用——知乎、钉钉组件访问失败解决

最近发现办公电脑知乎、钉钉内置组件访问不了&#xff0c;但同网络下笔记本可以访问&#xff1b;经过检测排除了目标服务异常、防火墙拦截的原因&#xff1b;最后发现是DNS的原因&#xff0c;调整DNS首先项1.1.1.1为114.114.114.114后解决&#xff0c;现插眼记录 首先排除拦截&…

Consumer Group

不&#xff0c;kafka-consumer-groups.sh 脚本本身并不用于创建 Consumer Group。它主要用于管理和查看 Consumer Group 的状态和详情&#xff0c;比如列出所有的 Consumer Group、查看特定 Consumer Group 的详情、删除 Consumer Group 等。 Consumer Group 是由 Kafka 消费者…

pandas与open读取csv/txt文件速度比较

pandas与open读取csv/txt文件速度比较 由于在工作中经常需要读取txt或csv文件&#xff0c;使用pandas与open均可以读取并操作文件内容&#xff0c;但不知道那个速度更快一些&#xff0c;所以写了一个脚本去比较在文件大小不同的情况下读取数据的速度 测试结果: 大小pandas速度…

观察者模式和订阅模式

观察者模式和订阅模式在概念上是相似的&#xff0c;它们都涉及到一个对象&#xff08;通常称为“主题”或“发布者”&#xff09;和多个依赖对象&#xff08;称为“观察者”或“订阅者”&#xff09;之间的关系。然而&#xff0c;尽管它们有相似之处&#xff0c;但在某些方面也…

自主研发,基于PHP+ vue2+element+ laravel8+ mysql5.7+ vscode开发的不良事件管理系统源码,不良事件管理系统源码

不良事件上报系统源码&#xff0c;不良事件管理系统源码&#xff0c;PHP源码 不良事件上报系统通过 “事前的人员知识培训管理和制度落地促进”、“事中的事件上报和跟进处理”、 以及 “事后的原因分析和工作持续优化”&#xff0c;结合预存上百套已正在使用的模板&#xff0…

取电快充协议芯片,支持全协议、内部集成LDO支持从UART串口读取电压电流消息

H004D 是一款支持全协议的受电端诱骗取电协议芯片&#xff0c;支持宽电压输入 3.3V~30V&#xff0c;芯片内部集成LDO&#xff0c;可输出 3.3V电压, 支持 通过UART 串口读取电压电流&#xff0c;支持定制功能&#xff0c;芯片采用QFN_20封装&#xff0c;线路简单&#xff0c;芯片…

科研数据处理工具Graphpad Prism 10.1+9.5下载安装教程

GraphPad Prism 是一个功能强大且易于使用的统计分析和绘图软件&#xff0c;专为生物医学研究设计而开发。 该软件提供了丰富的统计工具和绘图功能&#xff0c;使用者能够轻松进行数据分析和统计检验。它支持一系列的统计方法&#xff0c;包括T检验、方差分析、非参数检验、生…

Flutter:AnimatedIcon图标动画,自定义Icon通过延时Interval,实现交错式动画

配置vsync&#xff0c;需要实现一下with SingleTickerProviderStateMixinclass _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin{// late延迟初始化 AnimationControllerlate AnimationController _controller;overridevoid initStat…

【网络系统管理】2023年全国职业院校技能大赛:组策略--10套题组合--1

1、限制访问C盘; (1)搜索《我的电脑》 (2)用户配置\策略\管理模板\Windows组件\文件资源管理器 2、禁止运行run.exe; (1)搜索《应用程序》 (2)用户配置\策略\管理模板\系统

【LeetCode每日一题】——485.最大连续 1 的个数

文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【解题思路】八【时空频度】九【代码实现】十【提交结果】 一【题目类别】 数组 二【题目难度】 LeetCode 三【题目编号】 485.最大连续 1 的个数 四【题目描述】 给定…