在 C++ 中,模板分为函数模板和类模板两种。函数模板是用于生成函数的,类模板则是用于生成类的。

函数模板&模板函数     类模板&模板类  必须区分概念

函数模板是模板,模板函数时具体的函数
类模板是模板,模板类时具体的类
由函数模板实例化而得到的函数称为模板函数
由类模板实例化得到的类叫模板类

一.函数模板

函数模板的基本写法为:
template <typename 类型参数1, typename 类型参数2, ...> 
返回值类型  函数模板名(形参表)
{
    函数体
}

其中的 typename 关键字也可以用 class 关键字替换,例如:
template <class 类型参数1, class 类型参数2, ...>

举例,求两个值的最大值Max:

#include<iostream>
using namespace std;template <typename T>
T const& Max(T const& a, T const& b)
{return a < b ? b : a;
}int main()
{int i = 20;int j = 30;int result1 = Max(i, j); //编译到这一句时,编译器自动生成int Max(int, int)函数double f1 = 12.5;double f2 = 20.88;double result2 = Max(f1, f2); //编译到这句时,编译器自动生成double Max(double, double)函数string s1 = "Hello";string s2 = "world";string result3 = Max(s1, s2); //编译到这句时,编译器自动生成string Max(string, string)函数return 0;
}

模板在定义时,编译器不会对它编译,因为没有一个实体可用。只有在编译到某句代码时,如int result1 = Max(i, j);时,根据模板再将Max(i, j)编译成int Max(int, int)这样具体的函数。
编译器由模板自动生成函数的过程叫模板的实例化。由模板实例化而得到的函数称为模板函数。在大部分编译器中,模板只有在被实例化时,编译器才会检查其语法正确性。如果程序中写了一个模板却没有用到,那么编译器不会报告这个模板中的语法错误

编译器对模板进行实例化时,并非只能通过模板调用语句的实参来实例化模板中的类型参数,模板调用语句可以明确指明要把类型参数实例化为哪种类型。可以用:

函数名<实际类型参数1, 实际类型参数2, ...>

的方式告诉编译器应该如何实例化模板函数。例如下面的程序:

#include<iostream>
using namespace std;template <typename T>
T add(T n)
{return n+1;
}int main()
{cout << add(4) / 2 << endl; //正常写法,输出2cout << add<double>(4) / 2 << endl; //指明要用double来实例化add函数,输出2.5return 0;
}

第一句正常调用输出2,第二句为编译器指定类型,则输出2.5

二.类模板

人们需要编写多个形式和功能都相似的函数,因此有了函数模板来减少重复劳动;人们也需要编写多个形式和功能都相似的类,于是C++引入了类模板的概念,编译器从类模板可以自动生成多个类,避免了程序员的重复劳动。

类模板的写法如下:
template <class 类形参数1, class 类型参数2, ...>
class 类模板名称
{
    成员函数和成员变量
};
具体如下:

template<class T1, class T2>
class A
{
public:T1 value1;T2 value2;T1 add(T1 a, T2 b);
};

类模板中的成员函数放在类外定义时的语法如下:
template <class 类形参数1, class 类型参数2, ...>
返回值类型  类模板名<class 类塑参数1, class 类型参数2, ...>::成员函数名(形参表)
{
    。。。
}
具体如下:

template<class T1,class T2>
T1 A<T1, T2>::add(T1 a, T2 b)
{return a + b;
}

用类模板定义对象的写法如下:
类模板名<真实类型参数表> 对象名(构造函数实际参数表);
若构造函数无参的话则为:
类模板名 <真实类型参数表> 对象名;

下面实现一个简单的key,value的键值对----类模板mDictionary

实践中常常会碰到,某项数据记录由两部分组成,一部分是关键字,另一部分是值。关键字用来对记录进行排序和检索,根据关键字能查到值。例如,学生记录由两部分组成,一部分是姓名,另一部分是年纪。要能根据姓名对学生进行查询检索,key就是姓名,value就是年龄。

template<class T1, class T2>
class mDictionary
{
public:T1 key;      //关键字T2 value;    //值mDictionary(T1 k, T2 v) :key(k), value(v){};T2 getvalue(T1 k);
};template<class T1,class T2>
T2 mDictionary<T1, T2>::getvalue(T1 k)
{if (k == this->key)    //如果姓名传进来相同,则返回年龄{return this->value;}else{return 0;}
}int main()
{mDictionary<string, int> dic("Bob",22);std::cout << dic.getvalue("Bob")<<std::endl;    //返回22std::cout << dic.getvalue("Tom") << std::endl;  //返回0return 0;
}

实例化一个类模板时,如第main函数第一行-------mDictionary<string, int>  dic("Bob",22);
真实类型参数表中的参数是具体的类型名,如 string、int 等,它们用来一一对应地替换类模板定义中“类型参数表”中的类型参数。类模板名 <真实类型参数表>就成为一个具体的类的名字,就是mDictionary<string, int>就可以看成一个类型
如有一个类A, 初始化类A的时候,一般都是A  a;  mDictionary<string, int>就等价于A,可以看成一个A类型

编译器编译到这一行时,就会用 string 替换 mDictionary模板中的 T1,用 int 替换 T2,其余部分原样保留,这样就自动生成了一个新的类。这个类的名字编译器是如何处理的不需要知道,可以认为它的名字就是mDictionary<string, int>。也可以说,dic 对象的类型就是 Pair<string, int>。
mDictionary<string, int> 类的成员函数自然也是通过替换 mDictionary模板的成员函数中的 T1、T2 得到的。
编译器由类模板生成类的过程叫类模板的实例化。由类模板实例化得到的类叫模板类。

函数模板作为类模板成员
类模板中的成员函数还可以是一个函数模板。成员函数模板只有在被调用时才会被实例化。例如下面的程序:

#include <iostream>
using namespace std;
template <class T>
class A
{
public:template <class T2>             //定义新类型T2void Func(T2 t) { cout << t; }  //成员函数模板
};
int main()
{A<int> a;a.Func('K');  //成员函数模板Func被实例化a.Func("hello");return 0;
}

程序的输出结果是:Khello

这个例子与上面例子不同的是,mDictionary中的getvalue是一个类模板中的成员函数,没有定义新的模板,而Func函数是一个新的函数模板,在Func函数上面一句,定义了新类型T2,姑且先这样理解。其实只要了解有这种写法即可,既类模板中还可以定义函数模板。

C++ 函数模板类模板详解相关推荐

  1. C++模板及模板类(详解)

    目录 一.背景 二.代码 三.模板特化 一.背景 为什么要使用模板?以及为什么要使用模板类?为了减少重复代码,提高效率.比如你要实现一个相加函数,相加的类型有int,double,float,stri ...

  2. C++ - 类模板(class template) 详解 及 代码

    类模板(class template) 详解 及 代码 本文地址: http://blog.csdn.net/caroline_wendy/article/details/16906827 类模板(c ...

  3. C++函数模板的使用详解

    更多python.PHP.JAVA.C.C++教程请到友情连接: 菜鸟教程https://www.piaodoo.com 茂名一技http://www.enechn.com ppt制作教程步骤 htt ...

  4. ecshop模板smarty foreach详解

    Smarty目录: /libs Smarty的功能类目录 /tempalates 模板文件目录 /templates_c 模板缓存文件目录 /configs 配置文件目录 /cache 缓存文件目录 ...

  5. c++之模板初阶详解!

    c++之模板初阶详解 文章目录 c++之模板初阶详解 泛型编程 函数模板 函数模板概念 函数模板格式 模板的原理 函数模板的实例化 模板实例化的个数 对于同不同类型的传参! 如何处理这个问题呢? 关于 ...

  6. easycode 表配置_idea的easyCode的 MybatisPlus模板的配置详解

    EasyCode 插件 EasyCode 插件 是一款根据表结构生成代码的很方便的Idea插件, 强烈推荐. 并且可以自定义模板来控制生成的类 我在使用的过程中发现一些问题,现在把解决办法记录下来, ...

  7. 【C++ 语言】面向对象 ( 模板编程 | 函数模板 | 类模板 )

    文章目录 函数模板 类模板 代码示例 函数模板 1. 模板编程 : 类似于 Java 中的泛型编程 ; ① 函数模板 : 对应着 Java 中的泛型方法 ; ② 类模板 : 对应 Java 中的泛型类 ...

  8. 类模板,多种类型的类模板,自定义类模板,类模板的默认类型,数组的模板实现,友元和类模板,友元函数,类模板与静态变量,类模板与普通类之间互相继承,类模板作为模板参数,类嵌套,类模板嵌套,类包装器

     1.第一个最简单的类模板案例 #include "mainwindow.h" #include <QApplication> #include <QPush ...

  9. C++之模板类模板函数

    模板类 模板类的定义使用template<typename T>或template<class T>,将具有相同功能的代码合并,增加代码的简洁性和易读性.例如在计算凸包的例子中 ...

最新文章

  1. highly dynamic working process is a great approach for learning
  2. 【SQL编程】Greenplum 与 MySQL 数据库获取周几函数及函数结果保持一致的方法
  3. kotlin学习笔记——重载操作符
  4. 新浪微博2-找到用户的accessToken
  5. 4.9 利用对应的泛型替换Hashtable[转]
  6. Android APK 签名比对
  7. 如何自定义Struts2表单验证后的错误信息显示格式
  8. python的dataframe的groupby_python pandas.DataFrame.groupby()方法详解
  9. python将图片转换为字符_python如何将图片转换为字符图片
  10. 深度学习2.0-1.tensorflow的基础操作之数据类型
  11. 如何做好罗斯蒙特流量计管理工作
  12. H264的NAL单元详解
  13. 解决引用微信公众号获取的图片不能正常显示的问题,显示改图片来自微信公众号
  14. 【转】打造个性化ghostxp光盘另类教程(2)
  15. Boardcast03
  16. 【图形设计】什么是组织架构图?如何画组织架构图
  17. QS2016年全球高等教育系统实力排名 中国排名世界第八亚洲第一
  18. HbuilderX:uni app踩坑之uView-ui
  19. 广州、深圳NPDP认证考试取消通知
  20. JSP教师辅助办公软件教学进程管理系统yeclipse开发mysql数据库bs框架java编程jdbc详细设计

热门文章

  1. logback文件自动压缩,文件解压失败
  2. list对象中 根据某个属性 查询最大最小对象
  3. 工作中遇到的mouseout 与mouseleave的问题
  4. python.exe[8544]发生了未经处理的win32异常
  5. 99乘法表 c艹练习
  6. android如何玩完整光遇,光遇安卓端魔法季开启 光遇魔法季活动玩法攻略
  7. BusyBox下载安装教程
  8. 假期工作 炼金289
  9. java-php-python-游戏账号交易计算机毕业设计
  10. 【PHP】URL加密解密(可逆)