EasyC++39,函数模板
作者 | 梁唐
大家好,我是梁唐。
这是EasyC++系列的第39篇,来聊聊函数模板。
函数模板
所谓函数的模板,本质上也就是使用泛型来定义函数。
所谓的泛型其实也就是不定的类型,比如说我们使用vector
的时候,可以定义各种类型的vector
,可以定义存储int
型的vector
也可以定义存储float
类型的,也可以定义存储其他类型。我们在声明的时候将存储的类型当做参数传给了模板。
泛型可以用具体的类型,比如(int
或double
)替换,通过将类型作为参数传给模板,编译器会根据传递的参数类型生成该类型的函数。这种方式也被称为通用编程或者参数化类型。
举一个很简单的例子,比如说我们要实现一个函数交换两个变量的值。对于int
类型我们要实现一遍,对于double
类型我们又要实现一遍,如果还需要其他类型,那么又需要额外实现很多同样逻辑的函数。当然可以拷贝代码,但显然这样会很浪费时间,而且会使得代码变得臃肿。
这个时候我们就可以使用函数模板自动完成这一功能,函数模板允许以任意类型来定义函数,所以我们就可以这样实现:
template <typename T>
void swap(T &a, T &b) {
T temp = a;
a = b;
b = temp;
}
当我们要创建一个模板的时候,需要首先声明模板的类型,也就是template
语句做的事情。关键字typename
也是必须的,也可以使用class
代替。typename
关键字是在C++98标准添加的,所以在更早的版本中往往使用class
。在这个场景下,这两种方式是等价的。C++ Primer当中更建议使用typename
而非class
。
typename
之后跟的是类型的名称,我们可以使用任意的名字,一般来说习惯性地会使用字母T
。我们在使用的时候和普通函数并没有什么不同,当做普通函数使用即可。
template <typename T>
void swap(T &a, T &b) {
T temp = a;
a = b;
b = temp;
}
int i = 10, j = 20;
swap(i, j);
double a = 3.0, b = 4.0;
swap(a, b);
虽然我们只实现了一次函数,但是在编译的时候,编译器会将这个函数根据我们使用的情况生成多个版本。比如在上面的代码当中,我们使用了int
和double
两种类型的函数。编译器会替我们生成两份代码,也就是说最终代码上和我们手动实现函数重载是一样的,可以理解成一种方便我们程序编写的特性。
相关文章
- C++泛型编程,模板(二)类模板
- C++ 分区、文件夹大小获取、文件数据操作demo示例
- EasyC++40,模板重载
- EasyC++72,赋值运算符
- C++ | 矩阵类模板(类模板)
- C++递归和迭代的区别,并举例说明[通俗易懂]
- 【c++】【基础】【primer_plus】【第八章】 引用与模板函数
- C++结构体和类的区别_c++有结构体吗
- C++字符串加密_c++字符串连接函数
- C++11动态模板参数和type_traits
- C/C++开发基础——函数对象与std::function模板
- 【C++】初识模板
- 【Android 内存优化】Android 原生 API 图片压缩原理 ( 图片质量压缩方法 | 查找 Java 源码中的 native 方法对应的 C++ 源码 )
- 【C++】模板初阶
- 初识C++模板
- 【C++】你想要的——印刷模板儿
- 【C++】模板进阶
- C++中的标准化工厂—— 模板
- c++ 类模板函数模板的问题,模板函数不能是虚函数,虚函数不能是内联详解编程语言
- C++ pair类模板,STL pair类模板
- C++ STL标准模板库
- C++函数模板声明和实现
- 关于C/C++中的sideeffect(负效应)和sequencepoint(序列点)
- C++中函数模板的用法详细解析
- c++vector(向量)使用方法详解(顺序访问vector的多种方式)
- C++实现多线程查找文件实例
- C++函数模板与类模板实例解析
- Ruby使用C++扩展实例(含C++扩展代码示例)