当前位置:网站首页>有关函数模板的那些小知识-.-
有关函数模板的那些小知识-.-
2022-06-28 03:40:00 【皆自落】
本文介绍函数模板的概念、用途以及如何创建函数模板和函数模板的使用方法......
函数模板定义的一般形式如下:
template<类型形式参数表>
返回类型 函数名(形式参数表)
{
... //函数体
}
之前我们知道的交换两个变量的方法有宏定义、函数,这两种方式都能实现两个变量的交换,但是各有各的优缺点
宏定义:
-优点:
代码复用,适合所有的类型
- 缺点:
缺少类型检查,宏在预处理阶段就被替换掉,编译器并不知道宏的存在
函数:
- 优点:
真正的函数调用,编译器对类型进行检查
- 缺点:
类型不同需要重复定义函数,代码无法复用
上边两种方式都各有利弊,但是在C++中,存在泛型编程的概念:即不考虑具体数据类型的编程方式(如下)
对于函数体相同且函数的参数个数相同而参数类型不同的一系列函数而言,都是可以用函数模板来代替的,只需要定义一次函数模板即可。
函数模板通过template与typename(class代替 效果一致)两个关键字来定义,如下

上边就定义了一个变量交换的函数模板,在使用函数模板时有两种方式
- 自动类型推到调用 Swap(a, b)
- 具体类型显示调用 Swap<int>(a, b)
template<typename t>
t max(t a, t b)
{
return a > b ? a : b;
}
int main()
{
int a = 0;
//模板参数列表中只有一种数据类型,传入的实参也只有⼀种数据类型
//可以直接由函数模板生成模板函数
//隐式实例化
a = max(1, 2);
//模板参数列表中只有⼀种数据类型,但是此时传入的实参有两种数据类型
//在调用时需要强制的类型转换,保证实参的类型个数与模板参数列表的类型个数⼀致
//由函数模板生成模板函数时编译器不能做到自动的隐式转换,需要显示的强制转换
a = max(1, (int)2.0);
a = max((double)1, 2.0);
//显式转换也可以以尖括号形式的语法进行转换
//显式实例化
a = max<int>(1, 2.0);
a = max<double>(1, 2.0);
return 0;
}需要注意的是:函数模板不支持隐式类型转换
还有一招:显式具体化
函数模板的显式具体化是对函数模板的重新定义,具体格式如下所示:
template< > 函数返回值类型 函数名<实例化类型>(参数列表)
{
//函数体重新定义
}
显式实例化只需要显式声明模板参数的类型而不需要重新定义函数模板的实现,而显式具体化需要重新定义函数模板的实现。
//定义交换两个数据的函数模板,示例如下
template<typename T>
void swap(T& t1, T& t2)
{
T temp = t1;
t1 = t2;
t2 = temp;
}
//但现在有如下结构体定义
struct Student
{
int id;
char name[20];
float score;
};
//现在我们只想交换两个学生的id,那么我们就可以用显式具体化解决这个问题
template<> void swap<Student>(Student& s1, Student& s2)
{
int temp = s1.id;
s1.id = s2.id;
s2.id = temp;
}如果函数有多个原型,则编译器在选择函数调用时,非模板函数优先于模板函数,显式具体化模板优先于函数模板,例如下面三种定义:
void swap(int&, int&); //直接定义
template<typename T>void swap(T& t1, T& t2); //模板定义
template<> void swap<int>(int&, int&); //显式具体化如何理解呢?
int a, int b存在swap(a, b)调用,会优先调用直接定义的函数;如果没有,则调用显式具体化 ;两者都不存在,这时候才去调用模板函数。
函数模板也是可以重载的,和函数重载差不多,这里就不细说了。
使用函数模板时需要注意的问题:
1) < > 中的每一个类型参数在函数模板参数列表中必须至少使用一次。
例如,下面的函数模板声明是不正确的。
template<typename T1, typename T2>
void func(T1 t)
{
}函数模板声明了两个参数 T1 与 T2,但在使用时只使用了 T1,没有使用 T2。
2) 全局作用域中声明的与模板参数同名的对象、函数或类型,在函数模板中将被隐藏。
例如:
int num;
template<typename T>
void func(T t)
{
T num;
cout << num << endl; //输出的是局部变量num,全局int类型的num被屏蔽
}在函数体内访问的 num 是 T 类型的变量 num,而不是全局 int 类型的变量 num。(局部优先)
3) 函数模板中声明的对象或类型不能与模板参数同名。
例如:
template<typename T>
void func(T t)
{
typedef float T; //错误,定义的类型与模板参数名相同
}4) 模板参数名在同一模板参数列表中只能使用一次,但可在多个函数模板声明或定义之间重复使用。
例如:
template<typename T, typename T> //错误,在同一个模板中重复定义模板参数
void func1(T t1, T t2)
{}
template<typename T>
void func2(T t1)
{}
template<typename T> //在不同函数模板中可重复使用相同的模板参数名
void func3(T t1)
{}5) 模板的定义和多处声明所使用的模板参数名不是必须相同。
例如:
//模板的前向声明
template<typename T>
void func1(T t1, T t2);
//模板的定义
template<typename U>
void func1(U t1, U t2)
{
}6) 如果函数模板有多个模板参数,则每个模板参数前都必须使用关键字 class 或 typename 修饰。
例如:
template<typename T, typename U> //两个关键字可以混用
void func(T t, U u)
{}
template<typename T, U> //错误,每一个模板参数前都必须有关键字修饰
void func(T t, U u)
{}这次的文章也是到这里就结束了。
如果觉得有用的话,点个赞支持一下吧!
谢谢各位大佬
边栏推荐
- Building log analysis system with elk (III) -- Security Authentication
- Building a server monitoring platform with telegraf influxdb grafana
- Detailed explanation of iptables firewall rules and firewalld firewall rules
- ELK 搭建日志分析系统 + Zipkin服务链路追踪整合
- 基于正点原子stm32的mini板的TFTLCD显示实验
- Door level modeling - learning notes
- sqlserver 数据库之事物使用入门 案例
- 【MySQL】多表连接查询
- 数字电路学习笔记(二)
- 光伏板怎么申请ASTM E108阻燃测试?
猜你喜欢

Particle theory of light (photoelectric effect / Compton effect)

MSc 307 (88) (2010 FTPC code) Part 2 smoke and toxicity test

猫狗队列的问题

Several ways of sharing printers in LAN

Meichuang was selected into the list of "2022 CCIA top 50 Chinese network security competitiveness"

Chapter 1 Introduction to bash

Uncover the mystery of SSL and learn how to protect data with SSL

品达通用权限系统(Day 5~Day 6)

电学基础知识整理(二)

La norme européenne en 597 - 1 pour les meubles est - elle la même que les deux normes en 597 - 2 pour les ignifuges?
随机推荐
English grammar_ Adjective / adverb Level 3 - Comparative_ Useful Expressions
La norme européenne en 597 - 1 pour les meubles est - elle la même que les deux normes en 597 - 2 pour les ignifuges?
揭开SSL的神秘面纱,了解如何用SSL保护数据
Staggered and permutation combination formula
leetcode:494. All methods of adding and subtracting operators to the array to get the specified value
多项目设计开发·类库项目引入入门
Are the two flame retardant standards of European furniture en 597-1 and en 597-2 the same?
PostgreSQL 实现批量更新、删除、插入
MSc 307 (88) (2010 FTPC code) Part 5 low flame spread test
PostgreSQL implements batch update, deletion and insertion
Two methods of shell script parameter passing based on arm5718
Using elk to build a log analysis system (I) -- component introduction
数字电路学习笔记(二)
Talking about cloud primitiveness, we have to talk about containers
Detailed explanation of iptables firewall rules and firewalld firewall rules
05 mongodb summary of various column operations
测不准原理
Reading notes of top performance version 2 (II) -- CPU monitoring
MSC 307(88) (2010 FTPC Code) Part 5低播焰测试
Iso8191 test is mentioned in as 3744.1. Are the two tests the same?