【C++泛型编程】(一)函数模板和类模板

文章目录

  • (一)函数模板和类模板
    • 函数模板
    • 类模板
    • 模板的特化

(一)函数模板和类模板

C++泛型编程(Generic Programming)是一种编程范式,它允许程序员编写与参数无关的代码,也就是说这些代码可以在多种数据类型上重用,而无需为每个类型重新编写。

泛型编程的主要工具是模板(Templates),主要分为两种类型:函数模板和类模板。

函数模板

函数模板允许程序员编写一个通用的函数,该函数可以接受不同类型的参数,并在编译时根据提供的参数类型生成特定的函数版本。其语法如下:

template<typename T>
return_type functionName(T arg1, T arg2) {
    // 函数体
}
  • template — 声明创建模板
  • typename — 表面其后面的符号是一种数据类型,可以用class代替
  • T — 通用的数据类型。T只是一个约定的名称,可以将其改为其他标识符。
  • return_type : 返回值的类型,需要根据函数体指定,如:voidint或者T

函数模板的实例化

在使用函数模板时,编译器会根据传递的参数类型自动推导模板参数:

functionName(arg1, arg2); // 自动推导

或者你可以显式指定模板参数:

functionName<int>(arg1, arg2); // 显式实例化

示例:返回两个数中的较大者

#include <iostream>

// 函数模板:返回两个数中的较大者
template<typename T>
T max(T a, T b) {
    return (a > b) ? a : b;
}

int main() {
    std::cout << "Max of 5 and 3: " << max(5, 3) << std::endl;// 调用max<int>(5, 10)
    std::cout << "Max of 5.5 and 3.3: " << max(5.5, 3.3) << std::endl;// 调用max<double>(5.5, 3.3)
    return 0;
}
Max of 5 and 3: 5
Max of 5.5 and 3.3: 5.5

类模板

类模板则允许你编写一个通用的类,该类可以在编译时根据提供的类型参数生成特定的类版本。基本语法:

template<typename T>
// 类

类模板的定义包括构造函数、成员函数和成员变量等的定义,模板参数在类内部可以用作类型标识符:

template<typename T>
class ClassName {
public:
    ClassName(T value); // 构造函数模板
    void setValue(T value); // 成员函数模板

private:
    T data; // 数据成员
};

// 类模板的析构函数、构造函数和成员函数的实现通常放在类模板定义的外部。
template<typename T>
ClassName<T>::ClassName(T value) : data(value) {}

template<typename T>
void ClassName<T>::setValue(T value) {
    data = value;
}

类模板的实例化

在使用类模板时,需要为模板参数指定具体的类型。

ClassName<int> obj(42);

示例:一个通用数据类型的栈数据结构

#include <iostream>
// 类模板:一个简单的栈
template<typename T>
class Stack {
public:
    Stack();
    ~Stack(); 
    void push(T value);
    T pop();

private:
    T* data;
    int top;
    const static int size = 100;
};
// 类模板的构造函数
template<typename T>
Stack<T>::Stack() {
    data = new T[size];
    top = -1;
}
// 类模板的析构函数 
template<typename T>  
Stack<T>::~Stack() {  
    delete[] data; // 释放动态分配的数组  
}  
// 类模板的成员函数:入栈
template<typename T>
void Stack<T>::push(T value) {
    data[++top] = value;
}
// 类模板的成员函数:出栈
template<typename T>
T Stack<T>::pop() {
    return data[top--];
}

int main() {
    Stack<int> intStack;
    intStack.push(1);
    intStack.push(2);
    intStack.push(3);
    std::cout << intStack.pop() << std::endl; // 输出3
    std::cout << intStack.pop() << std::endl; // 输出2
    return 0;
}

模板的特化

模板的特化(Template Specialization)是一种对通用模板进行特殊处理的技术,以适应特定类型或条件的需求,可以分为全特化和偏特化两种类型:

  • 全特化:全特化是指对模板的所有模板参数都进行特化处理。例如,如果有一个模板类Test<T1, T2>,全特化可能是为Test<int, char>这样的具体类型提供特定的实现。

  • 偏特化:偏特化是指只对部分模板参数进行特化处理。例如,如果有一个模板类Test<T1, T2>,偏特化可能是为Test<T1, char>这样的部分具体类型提供特定的实现,其中T1仍然是一个模板参数。

示例:

#include <iostream>

// 通用模板类定义
template<typename T1, typename T2>
class Test {
public:
    void show() {
        std::cout << "General template" << std::endl;
    }
};

// 全特化示例:为Test<int, char>提供特定实现
template<>
class Test<int, char> {
public:
    void show() {
        std::cout << "Full specialization for Test<int, char>" << std::endl;
    }
};

// 偏特化示例:为Test<T1, char>提供特定实现,其中T1是任意类型
template<typename T1>
class Test<T1, char> {
public:
    void show() {
        std::cout << "Partial specialization for Test<T1, char>" << std::endl;
    }
};

int main() {
    // 使用通用模板类
    Test<double, double> t1;
    t1.show(); // 输出:General template

    // 使用全特化类
    Test<int, char> t2;
    t2.show(); // 输出:Full specialization for Test<int, char>

    // 使用偏特化类
    Test<float, char> t3;
    t3.show(); // 输出:Partial specialization for Test<T1, char>

    return 0;
}

对于函数模板,一般采用重载(Overloading)代替特化。例如,如果你有一个函数模板,并且想要为int类型提供特定的实现,你可以简单地重载该函数模板:

#include <iostream>

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

// 重载函数模板,为int类型提供特定实现
void print(int value) {
    std::cout << "Specialized print for int: " << value << std::endl;
}

int main() {
    print(10);     // 调用重载版本,输出 "Specialized print for int: 10"
    print(3.14);   // 调用通用模板版本,输出 "Generic print: 3.14"
    print("Hello"); // 调用通用模板版本,输出 "Generic print: Hello"
    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[oeasy]python0015_键盘改造_将esc和capslock对调_hjkl_移动_双手正位

键盘改造 &#x1f94b; 回忆上次内容 上次练习了复制粘贴 按键 作用 <kbd>y</kbd><kbd>y</kbd> 复制光标行代码 到剪贴板 <kbd>p</kbd> 粘贴剪贴板中的内容 <kbd>i</kbd> 切换到 插入模式 <kbd>h</kbd>…

网络技术-链路层可靠传输协议

可靠传输 在链路层传输中&#xff0c;可能出现的错误包括数据位出错、分组丢失、分组失序、分组重复等。可靠传输服务希望实现发送端发送什么&#xff0c;接收端就接收到什么。虽然下面将在链路层这一章节中介绍SW、GBN、SR三种协议&#xff0c;但要明确的是&#xff0c;可靠传…

typescript 模块化

模块的概念&#xff1a; 把一些公共的功能单独抽离成一个文件作为一个模块。 模块里面的变量、函数、类等默认是私有的&#xff0c;如果我们要在外部访问模块里面的数据&#xff08;变量、函数、类&#xff09;&#xff0c;需要通过export暴露模块里面的数据&#xff08;&#…

深度解读《深度探索C++对象模型》之C++的临时对象(二)

目录 临时对象的生命期 特殊的情况 接下来我将持续更新“深度解读《深度探索C对象模型》”系列&#xff0c;敬请期待&#xff0c;欢迎左下角点击关注&#xff01;也可以关注公众号&#xff1a;iShare爱分享&#xff0c;或文章末尾扫描二维码&#xff0c;自动获得推文和全部的…

51单片机keil编程中遇到的问题(持续更新)

字符无法打印报错 查看特殊功能寄存器名字的时候也会报错&#xff0c;因为无法编译通过&#xff0c;导致头文件的定义内容无法查找 keil编译中 error C127: ‘xx’: invalid storage class 这种一般是在编写头文件或源文件时&#xff0c;在声明函数的结尾没有添加分号&…

C++——list和string

list与string 前言一、listlist.hList的节点类List的迭代器类list类list.h 完整实现 list.cppList的节点类List的迭代器类list类list.cpp 完整实现 二、stringstring.hstring.cpp 总结 前言 C容器的学习开始啦&#xff01; 大家先来学习list&#xff01; 紧接着string和vector…

PGP加密技术:保护信息安全的利器

随着数字化时代的到来&#xff0c;个人和企业对信息安全的需求日益增长。PGP&#xff08;Pretty Good Privacy&#xff09;加密技术作为一项强大的加密工具&#xff0c;为保护敏感数据提供了一种有效的方法。本文将探讨PGP加密技术的基本原理、应用场景以及其在现代信息安全中的…

LeetCode:盛最多水的容器

文章收录于LeetCode专栏 盛最多水的容器 给你n个非负整数a1&#xff0c;a2&#xff0c;…&#xff0c;an&#xff0c;每个数代表坐标中的一个点(i, ai) 。在坐标内画 n 条垂直线&#xff0c;垂直线i的两个端点分别为(i, ai) 和 (i, 0)。找出其中的两条线&#xff0c;使得它们与…

如何实现网页上3D模型的展示、浏览和互动?

实现网页上3D模型的展示、浏览和互动&#xff0c;可以通过以下步骤进行&#xff1a; 1、创建3D内容&#xff1a;使用3ds max、Maya、blender、C4D等3D软件制作好3D模型。 2、设计3D应用&#xff1a;把制作好的模型导出为fbx、obj、dae、gltf、glb等格式文件&#xff0c;上传到…

不盖CNAS的证书就是无效的?证书哪些信息是“非必要”?

做设备校准的企业&#xff0c;大多数都是为了拿到仪器校准证书&#xff0c;而说起校准证书&#xff0c;很多人优先就是想到CNAS&#xff0c;CNAS作为校准行业重要的核心资质&#xff0c;无论是校准机构实力的证明&#xff0c;还是满足企业年审的需要&#xff0c;基本上都是关键…

Spring Security Oauth2 JWT 添加额外信息

目录 一、问题描述 二、实现步骤 1、自定义TokenEnhancer 2、配置授权服务器 3、自定义UserDetails的User类 三、参考文档 一、问题描述 Oauth2里默认生成的JWT信息并没有用户信息&#xff0c;在认证授权后一般会返回这一部分信息&#xff0c;我对此进行了改造。 Oauth…

大数据集成平台建设方案-word原件资料

基础支撑平台主要承担系统总体架构与各个应用子系统的交互&#xff0c;第三方系统与总体架构的交互。需要满足内部业务在该平台的基础上&#xff0c;实现平台对于子系统的可扩展性。基于以上分析对基础支撑平台&#xff0c;提出了以下要求&#xff1a; (1) 基于平台的基础架构&…

短视频矩阵系统源码/saas--总后台端、商户端、代理端、源头开发

短视频矩阵系统源码/saas--总后台端、商户端、代理端、源头开发 搭建短视频矩阵系统源码的交付步骤可以概括为以下几个关键环节&#xff1a; 1. **系统需求分析**&#xff1a;明确系统需要支持的功能&#xff0c;如短视频的上传、存储、播放、分享、评论、点赞等。 2. **技术选…

MySQL —— 数据类型

一、数值类型 以上表格整理了用来表示数值类型的数据类型&#xff0c;其中&#xff0c;接下来将介绍和展示其中几个类型的使用和各种细节 1.tinyint 越界测试&#xff1a;建立一个包含tinyint类型的表格&#xff0c;插入各中数据去查看结果&#xff0c;并且尝试插入边界数据和…

数字人捕捉、建模与合成

在感知系统中&#xff0c;我们与外部合作者一起创建逼真的 3D 人类&#xff0c;其行为可以像虚拟世界中的真实人类一样。这项工作在今天有许多实际应用&#xff0c;并且对于元宇宙的未来至关重要。但是&#xff0c;在感知系统中&#xff0c;我们的目标是科学的——通过重现人类…

PS五官与服装PSD文件大全,男女证件照制作必备素材

一、素材描述 男女证件照服装和五官等PSD文件大全&#xff0c;制作证件照的必备素材合集&#xff0c;轻松制作高端大气的证件照。什么是DR5&#xff1f;DR5是Delicious Retouch 5的简称&#xff0c;这是一款非常优秀的PS人像磨皮美容插件&#xff0c;DR5的主要功能就是针对人像…

AI换脸原理(4)——人脸对齐(关键点检测)参考文献2DFAN:代码解析

注意,本文属于人脸关键点检测步骤的论文,虽然也在人脸对齐的范畴下。 1、介绍 在本文中,重点介绍了以下几项创新性的成果,旨在为人脸关键点检测领域带来新的突破。 首先,成功构建了一个卓越的2D人脸关键点检测基线模型。这一模型不仅集成了目前最优的关键点检测网络结构,…

领导想提拔你,看的从来不只是努力

谁不曾做过努力工作&#xff0c;一路升职加薪的职业规划&#xff0c;现实却给很多人泼了一盆冷水。 在大家的普遍认知里&#xff0c;北上广普遍高薪&#xff0c;月入过万就是标配。 然而在逃离北上广的热门帖子下&#xff0c;有网友发出了声音&#xff1a; “我都35了&#xff…

XSS、CSRF、SSRF漏洞原理以及防御方式_xss csrf ssrf

这里写目录标题 XSS XSS攻击原理&#xff1a;XSS的防范措施主要有三个&#xff1a;编码、过滤、校正 CSRF CSRF攻击攻击原理及过程如下&#xff1a;CSRF攻击的防范措施&#xff1a; SSRF SSRF漏洞攻击原理以及方式SSRF漏洞攻击的防范措施 XMLXSS、CSRF、SSRF的区别 XSS、CSRF的…

落地护眼灯十大品牌哪款性价比高?品牌排行榜前十名全面揭晓!

落地护眼灯十大品牌哪款性价比高&#xff1f;落地护眼灯已经逐渐成为孩子日常使用率较高的电器之一&#xff0c;它的优点非常突出&#xff0c;对于学习、工作、绘画等环境都能够提供良好的健康环境&#xff0c;同时还携带多种智能调节功能&#xff0c;例如&#xff1a;入座感应…
最新文章