c++—模板(函数模板、类模板)

news/2025/2/6 4:08:27/

1. 模板是解决代码复用的最优解,其原理是为功能不变而参数数据类型不同的的程序提供一种代码共享机制,模板也是一种多态的实现,可以在编译器协助开发者生成代码,从而演化为面向模板元编程(面向编译器),是一种解决良好代码维护性、复用性的工具;

2. 在C语言中也可以进行宏定义进行函数模板,但是存在两个缺点:①不安全,因为宏定义只是简单的替换,不进行参数类型检查;②只可实现简单函数,不适合复杂函数;

3. 模板主要应用于函数模板、类模板两种情况下;

4. 函数模板:

    (1)语法

#include <iostream>
#include <string>template<typename T>  //函数模板声明
T my_max(const T &a, const T &b)
{return a > b ? a : b;
}int main()
{cout << my_max<int>(5,6) << endl;  //注意这里<int>指明T的类型return 0;
}

使用步骤:

①先声明函数模板:template<typename T>

②编写函数,注意里面的形参的类型均用T代替;

③在main函数中调用函数模板时,需要在函数名后面跟<int>或<char>等,表明本次调用的函数模板的类型是int还是char;

    (2)内部原理

①函数模板只是个模板,不能实际执行;

②在调用时,会根据指定的参数类型,依据函数模板实例化,生成模板函数;

③函数模板可以重载,条件均是前期重载定义的条件:形参表个数或者类型参数不同;

    (3)函数模板和普通函数的执行优先级

①先执行参数完全匹配的自定义普通函数;

②次之:参数匹配的模板函数;

    (4)可变参数模板:递归思路

#include <iostream>void test()    //递归结尾,即参数为0时结束
{
}template <typename T, typename...U>  //注意这个形式,有...
void tes(T && first, U&&... others)
{cout<<first<<endl;test(others...);
}
//可变参数函数,使用第一个参数first做一些事情后,继续递归其他参数;
//编译器内部对每一次递归调用形式(因为参数个数变化),都生成了固定的模板函数(实例化),会有很多;

5. 类模板

    (1)语法

①在类的定义前加模板声明:template<typename T>,T就是类型代名词;

②在类内所有需要用到数据类型的都用T代替;

③若成员函数在类外定义,则每个成员函数前面都要加相同的类模板声明,建议在类内定义;

④要使得成员函数的输出类型不受该类整体的类型模板声明T的限制,则可写成类的成员函数模板,使得该成员函数依据新的类型单独变化;

⑤可以利用using给模板起别名;

template <typename T>    //类模板声明
class Stack
{
public:Stack();void push(T num);T pop();template<typename U>    //该成员函数不受T的限制,根据实际U的类型而定void print(U num){cout<<num<<endl;}
private:int top;T data[SIZE];
}template void print<int>(int num);  //即针对int类型只实例化一次,只生成一个模板函数;int mian()
{Stack<int>s1;    //调用形式return 0;
}

    (2)隐式实例化、显式实例化

①隐式实例化会降低效率,因为每次调用模板时都会生成模板函数,无论前后的类型是否一致;

②显式实例化,相当于只生成一次模板函数,后面的再调用的隐式就不会再实例化了,本质上相当于函数声明,即调用模板时,前置声明一次,如下:

template void print<int>(const int &t);详见上图;

    (3)typename作用:在类模板中或者函数模板中访问一个类或者结构体中的自定义类型的时候,用typename修饰,放置语法歧义;

6. 模板的全特化与偏特化

    (1)特化处理的目的是对特殊的类型做特殊的处理,以求达到特定类型特定的功能(例如多输出几句话、特定的处理等等);

    (2)全特化:注意在全特化的类前加template<>

//类模板(泛化)
template <typename T1, typename T2>
class A
{T1 data1;T2 data2;
};//模板的全特化
template <>           //注意这里的全特化声明
class A<int double>   //这里也要指定特化的具体类型
{int data1;double data2;
};

    (3)偏特化示例,注意指定具体类型

//类模板(泛化)
template <typename T1, typename T2, typename T3>
class B
{
public:void myfunc(T2 b){cout<<"泛化函数"<<endl;}
};//偏特化
template <typename T2>    //没有偏特化的参数类型还要注明,不能丢
class B<int, T2, int>     //已经偏特化的参数类型要在类型定义后面加上具体类型
{
public:void myfunc(T2 b){cout<<"偏特化函数"<<endl;} 
};

    (4)全特化与偏特化的区别

①全特化实际是更加具体地指明所有的参数的固定类型;

②偏特化实际是一部分参数明确了具体的类型,而不是所有的;或者所有参数都降低了类型范围,减少了系统类型推导时间,例如T→T*,或者const修饰;

③若在特化处理中出现偏特化冲突时,用全特化处理;

④一般用类型的全特化较多,函数的全特化尽量不要用,而是直接写一个自定义的普通函数;

    (5)模板元编程

        为编译器而编码,旨在利用编译期间为生成代码而进行的编程;工作原理是利用类模板,通过编译器生成各种各类的模板类;同时利用const等关键字让系统自动回收垃圾;


http://www.ppmy.cn/news/100539.html

相关文章

CAPL(vTESTStudio) - CAPL控制程控电源IT6332A

目录 为什么要使用CAPL控制程控电源? 一、程控电源的选择 二、程控电源通信协议

整型在内存中的存储,整型最大值最小值的推导,以及大小端的介绍

整数在内存中的存储 我们知道C语言有以下基本的整型类型&#xff1a; char //字符型 short //短整型 int //整型 long //长整型 long long //更长的整型我们可以用操作符sizeof和在<limits.h>头文件下&#xff0c;可以查看到各基本数据类型的所占字节的大小以及整形所…

Kubernetes_核心组件_kubelet_kubelet服务全解析

文章目录 前言一、查看kubelet当前运行1.1 查看kubelet当前运行1.2 kubelet配置文件1.3 kubelet启动参数文件1.4 kubelet启动全过程 (自定义启动参数文件) 二、kubelet启动过程2.1 kubelet启动过程2.2 自定义kubelet所有文件并运行步骤1&#xff1a;新建静态token文件和user&am…

在 Git 中撤消更改的 6 种方法!

目录 1. 修改最近的提交 2. 将分支重置为较旧的提交 硬重置 软重置分支 创建备份分支 3. 交互式变基 删除旧提交 改写提交消息 编辑旧提交 压缩 4. 还原提交 5. 签出文件 6. 使用 Git Reflog 当使用 Git 进行项目代码管理时&#xff0c;难免会出现一些错误操作或需…

list常见接口的使用(基于c++标准库中的STL)

前言 list是重要的容器了解它的常见接口以及使用是很有必要的&#xff0c;为什么有了vector还要有list呢&#xff1f;因为vector存在一些缺陷&#xff0c;比如&#xff1a;容量满了要扩容&#xff0c;扩容是要付出代价的&#xff08;性能的损失&#xff09;&#xff0c;存在空…

任务7 课程信息管理系统

系列文章 任务7 课程信息管理系统 已知课程的信息包括&#xff1a;课程编号&#xff0c;课程名称&#xff0c;课程性质&#xff08;必修、选修&#xff09;&#xff0c;课时&#xff0c;学分&#xff0c;考核方式&#xff08;考试、考查课&#xff09;&#xff0c;开课学期&a…

DIP:依赖反转原则

系列文章目录 C高性能优化编程系列 深入理解设计原则系列 深入理解设计模式系列 高级C并发线程编程 DIP&#xff1a;依赖反转原则 系列文章目录1、依赖反转原则的定义和解读2、稳定的抽象层3、依赖倒置原则和控制反转、依赖注入的联系小结 1、依赖反转原则的定义和解读 SOIL…

11、渗透性测试及验收测试

目录 什么是安全测试 安全测试与常规测试的区别 SQL注入漏洞 SQL注入漏洞会带来以下几种常见的后果&#xff1a; SQL注入漏洞攻击流程 注入点类型 SQL注入的防范措施 XSS跨站脚本漏洞 XSS原理解析 XSS类型 1、反射型XSS 2、存储型XSS 3、存储型XSS 查找XSS漏洞的…