模板概述

     模板,按建筑学的说法是:施工时浇筑混凝土用的成组模型板;而模板之词,恐怕可释之为模型之板,顾名思义,模板为一套规定好了规范准则的样板。既然为样板,自然是可被多方使用;而准则既已定好,那么限制亦是必然存在呢。程序界中的模板,原义也应取于此。模板所用之样板根据模板的不同可为实现了一定算法的函数,也可为规定好了内部数据结构和操作的类;而所施加之限制则为合乎模板定义的类型参数。至于模板定义的类型参数,不外乎:数目相同、操作完备呢。
     模板按其使用,可归结为两大类:函数模板和类模板。函数模板和普通函数相比,可谓异曲同工。普通函数也算得上是一种模板,只是施加于普通函数上的限制严格于函数模板而已。普通函数实现了基本的算法,调用函数时,需提供相同数目,相同类型的实参来代替形参。而模板函数除了要求参数的数目相同外,将形参的类型作了放大,因而其使用范围也随之变大。模板函数的实参类型只需要具有形参类型所必须的操作即可。
     下面的例子定义了三个函数:
 1None.gif//max.h
 2None.gif#include <iostream>
 3None.giftemplate <typename T>
 4ExpandedBlockStart.gifContractedBlock.gifinline T const& max(T const& a,T const& b)dot.gif{
 5InBlock.gif    std::cout<<"你调用的是两个参数的模板函数!"<<std::endl;
 6InBlock.gif    return a>b?a:b;
 7ExpandedBlockEnd.gif}

 8None.gif
 9None.giftemplate <typename T1,typename T2>
10ExpandedBlockStart.gifContractedBlock.gifinline T1 const& max(T1 const& a,T2 const&b)dot.gif{
11InBlock.gif    std::cout<<"你调用的是两个参数的模板函数,且参数类型不同!"<<std::endl;
12InBlock.gif    return a>b?a:b;
13ExpandedBlockEnd.gif}

14None.gif
15ExpandedBlockStart.gifContractedBlock.gifinline int const& max(int const& a,int const& b)dot.gif{
16InBlock.gif    std::cout<<"你调用的是两个参数的普通函数!"<<std::endl;
17InBlock.gif    return a>b?a:b;
18ExpandedBlockEnd.gif}

19None.gif
20None.giftemplate <typename T>
21ExpandedBlockStart.gifContractedBlock.gifinline T const& max(T const& a, T const& b ,T const& c)dot.gif{
22InBlock.gif    std::cout<<"你调用的是三个参数的模板函数!"<<std::endl;
23InBlock.gif    T d;
24InBlock.gif    d=a>b?a:b;
25InBlock.gif    return d>c?d:c;
26ExpandedBlockEnd.gif}

27None.gif
     其中,第一和第三个函数都为模板函数,而第二个函数为普通函数。下面的代码使用这些函数:
 1None.gif#include <iostream>
 2None.gif#include <string>
 3None.gif#include "max.h"
 4None.gif
 5ExpandedBlockStart.gifContractedBlock.gifint main()dot.gif{
 6InBlock.gif    int i=42;
 7InBlock.gif    std::cout<<"max(7,i) is "<<::max(7,i)<<std::endl;
 8InBlock.gif
 9InBlock.gif    double f1=3.45;
10InBlock.gif    double f2=-9.34;
11InBlock.gif    std::cout<<"max(f1,f2) is"<<::max(f1,f2)<<std::endl;
12InBlock.gif    
13InBlock.gif    //下面的两行代码是正确的,前者明确指明参数的类型;后者通过类型转换都使得代码能正确运行。
14InBlock.gif    std::cout<<"max(f1,i) is"<<::max<double>(f1,i)<<std::endl;
15InBlock.gif    std::cout<<"max(f1,i) is"<<::max(f1,static_cast<double>(i))<<std::endl;
16InBlock.gif
17InBlock.gif    std::cout<<"max(f1,f2,f3)"<<::max(12.0,13.0,11.5)<<std::endl;
18InBlock.gif    std::cout<<"max(char,int)"<<::max('a',12)<<std::endl;
19InBlock.gif    std::cout<<"max(f1,i) is"<<::max(f1,i)<<std::endl;
20InBlock.gif    std::cout<<"max(int,int)"<<::max<double>(12,34)<<std::endl;
21InBlock.gif    std::cin>>i;
22ExpandedBlockEnd.gif}

     通过上面的代码的运行结果,我们可以发现第14行的代码调用的都是普通函数版本的max函数,而第18、19行的代码调用的是两个参数类型不同的模板函数。
     上面的代码说明了模板函数的定义、模板函数的重载和使用等方面的问题,比较有意思的是模板函数的重载。和普通函数一样,模板函数也能重载,可以为模板函数定义参数数目不同的重载函数,也可以定义数目相同但参数类型不同的重载函数,而普通函数我们也可以当作是指定了具体类型的模板函数来处理。经过这样的处理,我们可以看出,模板函数的重载和普通函数的重载方式大同小异。
     说完了模板函数的重载,我们再谈谈重载模板函数的使用,使用模板函数时,采用最符合原则进行调用,这也是为什么第14行的代码调用的是普通函数,而18,19行的代码调用的是两个参数类型不同的模板函数的原因。如果我们将第18,19行代码调用的模板函数去掉,那么代码仍然可以运行,其调用的将是普通函数,因为char和float都可以转换为int,最符合的函数原型是普通函数。
    说完了函数模板,该谈谈模板类了,可惜肚子开始呱呱叫了,只好下回分解呢。 
     我们继续前面的话题。模板函数还是十分简单的,模板类则复杂的多。同模板函数一样,也能对模板类实施重载。当然,对类而言,使用重载似乎不是那么合适了,因而我们使用专门的词来称呼-专门化(Specialization)。而这种specialization,同模板函数重载一样,可以是完全specialization,也可是部分specialization(partial specialization),其实我们完全可以沿用前面处理函数的观点,将普通类(完全specialization的类)当作是一种特殊的模板类,那样无论是何种specialization,事实上都是模板类,只是类型参数的限制不同而已。如果进行这样的统一以后,对于重载模板类的定义、使用就同模板函数完全一致了,这里就不再多费口舌了。
     模板类有一个模板函数不具有的特性-默认参数类型。模板类的类型参数设定时可以给出默认类型,使用的时候如果对于该参数不给出实参类型,将使用默认类型代替形参类型,这同函数中的默认参数值是一样的,不过模板函数是不允许这样做的。

转载于:https://www.cnblogs.com/lotusswan/archive/2005/09/01/227727.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/386456.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

我凭什么拿到了阿里、腾讯、今日头条3家大厂offer?通用流行框架大全

前言 从毕业到现在面试也就那么几家公司&#xff0c;单前几次都比较顺利&#xff0c;在面到第三家时都给到了我offer&#xff01;前面两次找工作&#xff0c;没考虑到以后需要什么&#xff0c;自己的对未来的规划是什么&#xff0c;只要有份工作&#xff0c;工资符合自己的要求…

解决读写分离过期读的几个方案

mysql读写分离的坑 读写分离的主要目标是分摊主库的压力&#xff0c;由客户端选择后端数据库进行查询。还有种架构就是在MYSQL和客户端之间有一个中间代理层proxy&#xff0c;客户端之连接proxy&#xff0c;由proxy根据请求类型和上下文决定请求的分发路由。 客户端直连方案&am…

Feign接口 多线程问题

Spring Cloud Feign传输Header&#xff0c;并保证多线程情况下也适用 一、现象 微服务在生产中&#xff0c;常遇到需要把 header 传递到下一子服务的情况&#xff08;如服务A访问服务B的接口&#xff0c;需要传递header&#xff09;&#xff0c;网上大多数的方案是实现 Request…

serial port 的操作

import serial①选择设备serserial.Serial("/dev/ttyUSB0",9600,timeout0.5) #使用USB连接串行口serserial.Serial("/dev/ttyAMA0",9600,timeout0.5) #使用树莓派的GPIO口连接串行口serserial.Serial(1,9600,timeout0.5)#winsows系统使用com1口连接串行口s…

我在华为做Android外包的真实经历!吊打面试官系列!

导语 本部分内容是关于Android进阶的一些知识总结&#xff0c;涉及到的知识点比较杂&#xff0c;不过都是面试中几乎常问的知识点&#xff0c;也是加分的点。 关于这部分内容&#xff0c;可能需要有一些具体的项目实践。在面试的过程中&#xff0c;结合具体自身实践经历&…

logstash windows

最新在研究elastic stack (elk) &#xff1a; logstash 安装&#xff0c;下载最新版本的logstash: 点击打开链接 解压到磁盘根目录下&#xff1a;在logstash>bin 1、目录下创建&#xff1a;logstash.conf 2、输入内容: # Sample Logstash configuration for creating …

H3C端口状态

转载于:https://www.cnblogs.com/fanweisheng/p/11153315.html

还有人不知道什么是AndroidX的吗?文末领取面试资料

谈起Android框架体系架构&#xff0c;我先提个问&#xff1a;什么是Android框架体系架构 &#xff1f; Android系统构架是安卓系统的体系结构&#xff0c;android的系统架构和其操作系统一样&#xff0c;采用了分层的架构&#xff0c;共分为四层&#xff0c;从高到低分别是And…

zookeeper+kafka+logstash+elasticsearc+kibana

研究背景 1、之所以选用kafka是因为量起来的话单台logstash的抗压能力比较差 2、为了解决整个链路查询的问题&#xff0c;多个Feign传层的话&#xff0c;可以按照一个ID进行穿层&#xff0c;所以采用logback的MDC进行对唯一标识存储并且在Feign的调用链放在Header里&#xff…

还没吃透内存缓存LruCache实现原理的看这篇文章,跳槽薪资翻倍

目前情况&#xff1a;10届某民办大学本科生&#xff0c;实际接触Android年限6年多了&#xff0c;工作年限五年半&#xff08;注意&#xff0c;我说的是工作年限&#xff0c;不是工作经验&#xff09;&#xff0c;今年1月份裸辞后歇了大半年&#xff0c;经常一周也收不到几个off…

利用 Docker 搭建单机的 Cloudera CDH 以及使用实践

利用 Docker 搭建单机的 Cloudera CDH 以及使用实践 想用 CDH 大礼包&#xff0c;于是先在 Mac 上和 Centos7.4 上分别搞个了单机的测试用。其实操作的流和使用到的命令差不多就一并说了: 首先前往官方下载包&#xff1a; https://www.cloudera.com/downloads/quickstart_vm…

前端有用JavaScript技巧

数组去重 var arr [1, 2, 3, 3, 4];console.log(...new Set(arr))// [1, 2, 3, 4] 数组和布尔值 有时我们需要过滤数组中值为 false 的值. 例如(0, undefined, null, false) var myArray [1, 0 , undefined, null, false];myArray.filter(Boolean);//[1] 合并对象 const page…

还没吃透内存缓存LruCache实现原理的看这篇文章,面试必会

前言 这篇文章主要是分享今年上半年的面试心得&#xff0c;现已就职于某大厂有三个月了&#xff0c;近期有很多公司均已启动秋招&#xff0c;也祝大家在 2020 的下半年面试顺利&#xff0c;获得理想的offer&#xff01; 之前找工作的那段时间感想颇多&#xff0c;总结一点面试…

fastjson反序列化漏洞原理及利用

重要漏洞利用poc及版本 我是从github上的参考中直接copy的exp&#xff0c;这个类就是要注入的类 import java.lang.Runtime; import java.lang.Process; public class Exploit { public Exploit() { try{ // 要执行的命令 String commands "calc.exe"; Process pc …

这个回答让我错失offer!offer拿到手软

开头 每到“金三银四”的季节&#xff0c;总人很多人去寻找名叫“面经”一样的东西&#xff0c;其实就是一个个具体的题目&#xff0c;然后临阵磨枪&#xff0c;去“背”答案&#xff0c;如果一直是这样的话&#xff0c;我相信你的能力不会有任何提高&#xff0c;即使工作三年…

Spark Windows

本文主要是讲解Spark在Windows环境是如何搭建的 一、JDK的安装 1、1 下载JDK 首先需要安装JDK&#xff0c;并且将环境变量配置好&#xff0c;如果已经安装了的老司机可以忽略。JDK&#xff08;全称是JavaTM Platform Standard Edition Development Kit&#xff09;的安装&…

ts

ts文件中使用以下注释来临时忽略规则出现的错误。如在定义变量是为定义类型就报错误 // tslint:disable——忽略该行以下所有代码出现的错误提示// tslint:enable——当前ts文件重新启用tslint// tslint:disable-line——忽略当前行代码出现的错误提示// tslint:disable-next-l…

这个回答让我错失offer!成功收获美团,小米安卓offer

前言 我们移动开发程序员应该首先明白一个要点&#xff0c;能够学习的东西可以区分为『知识』和『技能』。 知识&#xff0c;就是你知道就知道、不知道就不知道的东西&#xff0c;比如『计算机系统中一个字节是包含8个bit』&#xff0c;你知道了之后就算掌握了。 技能&#…

vue 双数据绑定原理

Vue的双向数据绑定原理是什么&#xff1f; 答&#xff1a;vue.js 是采用数据劫持结合发布者-订阅者模式的方式&#xff0c;通过Object.defineProperty()来劫持各个属性的setter&#xff0c;getter&#xff0c;在数据变动时发布消息给订阅者&#xff0c;触发相应的监听回调。 具…

Java lamda表达式快速分组

public class ProductDto {private long month;private String cate;private double count;} 分组 Map<String,List<ProductDto>> categoryMap alllist.getValue().stream().collect(Col lectors.groupingBy(ProductDto::getCate));求和 Double sumCount catego…