最近在学习C++的过程中,发现函数模板的功能非常多,并且能减少许多工作量,减少重复代码,在这里对学习过程中的内容和经验进行一下总结。

        目录

1.函数模板的格式:

2.函数模板的调用方式

3.普通函数与函数模板的区别

4.函数模板的重载

5.函数模板特化

6.函数模板嵌套

7.函数模板的非类型参数

8.总结


1.函数模板的格式:

template<class T1,typename T2>  {函数返回值类型} {函数名} (参数) {        }

其中 class 与 typename 的作用一致,都是用来声明一个通用类型,也可叫做虚拟类型;

2.函数模板的调用方式

对于函数模板有两种调用方式,第一种是显式调用方式,第二种则是隐式调用方式。

第一种:显式调用格式

{函数名}<实际类型1,实际类型2>(参数列表);

例:

#include <iostream>using namespace std;template <class T>
void fun(T temp)
{cout << temp << endl;
}int main()
{fun<int>(30);return 0;
}

第二种:隐式调用格式

{函数名}(参数列表);

例:

#include <iostream>using namespace std;template <class T>
void fun(T temp)
{cout << temp << endl;
}int main()
{fun(30);return 0;
}

但对于隐式调用来说有一个问题不能忽视,那就是如果有一个与函数模板同名的一个普通函数重载,则在使用隐式调用时会优先调用普通函数而非调用模板函数。

例:

#include <iostream>using namespace std;template <class T>
void fun(T temp)
{cout << temp << endl;cout << "此处是模板函数" << endl;
}void fun(int temp)
{cout << temp << endl;cout << "此处是普通函数" << endl;
}int main()
{fun(30);return 0;
}

终端输出结果:

30

此处是普通函数

3.普通函数与函数模板的区别

  • 对于普通函数,其参数数据类型只能与一种数据类型相匹配,当使用普通函数需要匹配多种数据类型时,只能使用函数重载来实现,而函数模板则可以直接与多种数据类型相匹配,极大减少了代码量。
  • 函数模板只有在调用时才会构建函数,而普通函数则是在编译时就会构建函数。
  • 普通函数在调用的时候会自动进行隐式类型转换,而函数模板则不会。

4.函数模板的重载

与普通函数的重载相类似,都是在同一个作用域内函数名相同且参数列表不同。

例:以下是参数顺序不同的重载

#include <iostream>using namespace std;template <class T1,class T2>
void fun(T1 a,T2 b)
{cout << "这是fun1函数" << endl;
}template <class T1,class T2>
void fun(T2 a,T1 b)
{cout << "这是fun2函数" << endl;
}int main()
{fun<int,double>(10,10.0);fun<int,double>(10.0,10);return 0;
}

终端输出结果:

这是fun1函数
这是fun2函数

5.函数模板特化

当函数模板需要处理一些特定的类型,诸如类、数组、结构体等时,无法对这些类型的数据进行处理,为了解决这种局限性,在定义函数模板时,直接确定好类型,这就是特化的函数模板。

如果传入的是自定义类型,并且和特化版本匹配,会优先使用特化版本。

函数模板特化格式:

template<>{函数返回值}{函数名}(类名& 对象){        }

例:

#include <iostream>
#include <string>
using namespace std;class person
{
public:int age;string name;
public:person(int age,string name);~person();
};person::person(int age,string name)
{this->age = age;this->name = name;
}person::~person()
{
}template<class T>
bool compare(T a,T b)
{if(a == b){return true;}else return false;
}template<>
bool compare(person a,person b)
{if(compare(a.age,b.age) && compare(a.name,b.name) ){return true;}else return false;
}int main()
{person a(1,"fff");person b(1,"fff");cout << compare(a,b) << endl;return 0;
}

注意:当使用函数模板特化时,需要在上方定义一个相同函数名的函数模板,否则编译器会报错。或者可以在函数模板的尖括号中加上 class {通用类型名} ,也可以避免编译器报错。

6.函数模板嵌套

有时为了方便,会直接在函数模板中直接调用另一个函数模板,比如需要使用函数模板比较出2至4种参数的最大值,此时就能使用函数模板嵌套来减少代码量。

例:

#include <iostream>using namespace std;template <class T>
T Max(T a,T b)
{T max = a;if(max < b){max = b;}return max;
}template <class T>
T Max(T a,T b,T c)
{T max = Max(Max(a,b),c);return max;
}template <class T>
T Max(T a,T b,T c,T d)
{T max = Max(Max(a,b,c),d);return max;
}int main()
{cout << "max = " << Max(10,20) << endl;cout << "max = " << Max(30,2,13) << endl;cout << "max = " << Max(11,33,24,1) << endl;return 0;
}

7.函数模板的非类型参数

当需要往函数模板中传入一个特定的确定参数但不希望将该参数放在小括号中时,即可通过使用非类型参数实现。

格式:

template <class T,{基本数据类型}{变量名}>{函数返回值类型}{函数名}(T& {参数名});

例:

#include <iostream>using namespace std;template <class T,int size>
void display(T* buf)
{for (size_t i = 0; i < size; i++){cout << buf[i] << endl;}}int main(int argc, char const *argv[])
{int num[] = {10,20,11,33,44,11,23};const int size = sizeof(num)/4;display<int,size>(num);return 0;
}

特别注意:在使用非类型参数时,非类型参数都是常量,在函数中不允许被修改,所以在定义时需要将该参数定义为const类型,否则编译器会报错。

8.总结

如上,此文仅为本人在C++学习过程中对函数模板的经验总结,对于函数模板还有许多便利的使用场景及方法值得我们去探究。如果有对于函数模板不明白之处的人希望该文能帮到你。

C++ 函数模板的使用相关推荐

  1. C语言小知识:typedef\函数模板\

    (1)typedef用法: typedef为C语言的关键字,作用是为一种数据类型定义一个新名字.这里的数据类型包括内部数据类型(int,char等)和自定义的数据类型(struct等).在编程中使用t ...

  2. [C++再学习系列] 函数模板和类模板

    函数模板和类模板 C++ 提供类模板和函数模板.函数模板允许重载 ,而类模板不允许重载(类无重载概念).类模板可以进行全特化和偏特化,而函数模板仅能够全特化 .因此,写一个看似函数模板偏特化的函数模板 ...

  3. C++ 函数模板和排序的函数模板——学习笔记

    我们在使用重载函数时,只是使用了函数名,而函数体还是得分别定义,在C++中函数模板为我们很好的解决了这个问题. 1.函数模板的声明 函数模板可以用来创建一个通用的函数,以支持多种不同的形参,避免重载函 ...

  4. 函数重载和 函数模板

    一.函数重载(overload) #include <iostream> using namespace std;//计算两个参数a,b的乘积的函数 int product(int a,i ...

  5. C++_static,类模板、函数模板、namespace

    C++_static,类模板.函数模板.namespace 1.static 2.类模板 3.函数模板 4.namespace 5.深入,更多细节 参考:侯捷<C++面向对象高级编程>

  6. 判断exception类型_C++核心准则T.44:使用函数模板推断类模板参数类型(如果可能)...

    T.44: Use function templates to deduce class template argument types (where feasible) T.44:使用函数模板推断类 ...

  7. 第四章函数作业题,函数模板

    什么是函数模板? 就是不写具体的数据类型,而用一个虚拟类型来代表,这样可以提高效率. #include <iostream> using namespace std;template< ...

  8. C++走向远洋——61(项目一、排序函数模板)

    */* Copyright (c) 2016,烟台大学计算机与控制工程学院* All rights reserved.* 文件名:text.cpp* 作者:常轩* 微信公众号:Worldhello* ...

  9. [转]C++函数模板与模板函数

    1.函数模板的声明和模板函数的生成 1.1函数模板的声明 函数模板可以用来创建一个通用的函数,以支持多种不同的形参,避免重载函数的函数体重复设计.它的最大特点是把函数使用的数据类型作为参数. 函数模板 ...

  10. templateclass T函数模板

    //参考  http://prglab.com/cms/pages/c-tutorial/advanced-concepts/templates.php 函数模板( Function template ...

最新文章

  1. web初级开发的那些坑
  2. poj3621 Sightseeing Cows --- 01分数规划
  3. 简解Css - 多变的边框
  4. Java中 读-写 文件 BufferedReader BufferedWriter
  5. Matlab | Matlab从入门到放弃(12)——基于Matlab的特征值与奇异值分解
  6. Linux中xml导入数据库,XML数据库 BaseX
  7. 这周,全球首个IT技术全中文免费学习平台诞生了!太惊艳!
  8. 1.9 编程基础之顺序查找 07 不与最大数相同的数字之和
  9. 【kafka】kafka 判断消费组死掉方案 group dead
  10. Ubuntu 11.10 make menuconfig 失败的解决方法
  11. 打开eclipse报错 Version 1.7.0_80 of JVM is not suitable for this product
  12. Android如何谷歌搜索,android – 如何从谷歌地方检索搜索建议?
  13. 吐血推荐珍藏的Chrome插件
  14. Ubuntu硬盘的分区、格式化、挂载
  15. Centos7 源码安装mysql5.6
  16. turtle绘制八边形、八角边形
  17. 【Linux】云服务器的购买与Linux远程连接
  18. 文墨绘学:教育培训微信营销方案
  19. 验证码—基本功能实现02_点击重新获取验证码
  20. Drools学习笔记4-第一个例子

热门文章

  1. 自媒体快速写文章和获取素材的几大途径
  2. UIWebView和WKWebView的使用及js交互
  3. NLP任务样本数据不均衡问题解决方案的总结和数据增强回译的实战展示
  4. 跟据经纬度实现附近搜索
  5. Android程序记事本源码,安卓记事本程序源代码(Android Notepad program source code).doc...
  6. 华硕灵耀U4100UQ:将匠心设计融入到骨子里的笔记本电脑
  7. HiveSQL调优手段有哪些?
  8. 个人网页中心html,个人网页
  9. [机器学习] 超参数优化算法-SuccessiveHalving, BH与BOHB
  10. FFN MLP dense 权重矩阵 全连接