C++ 函数模板基础知识
为什么要引入模板:为了避免代码重复,程序员可以编写脱离数据类型通用模板。
模板的分类:函数模板 + 类模板
注意:模板的声明或定义只能在全局,命名空间或类范围内进行。不能在函数内进行,比如不能在main函数中声明或定义一个模板。
函数模板:
定义:
函数模板:关键词在后两个字,模板:提供一类函数的抽象,以任意类型T为参数把具有相同程序正文的一类函数抽象出来,可以适合任意类型T的参数。
模板函数:重点在函数,是对函数模板进行参数实例化后的结果,是一个具体的函数。
什么时候使用函数模板:会有一类函数,它们几乎相同,唯一的区别就是形参类型不同。这时我们可以撇开不同的数据类型,创建一个模板,并把数据类型也当作一个参数而设计一个模板
举例说明:编写比较两个整型数据大小的函数,它只适合于整型数据。如果是比较两个浮点型数据,就需要重新编写另外一个函数。如果我们使用函数模板的话,可以把数据类型忽略,编写一个max函数,既可以实现int,也可以实现浮点型。
语法:
template <class T> //模板声明格式
返回值类型 函数名(模板形参表) //模板函数形参表
{
//函数定义体
}
函数调用:函数名(模板实参表) //和普通的函数调用没有区别,只不过运行时,系统会首先根据参数类型确定数据类型,生成一个模板函数。
说明:
1、这里的class指一类的意思
2、参数有两种:类型参数 + 函数参数
3、T 为类型参数,可以是预定义的数据类型,可以是用户自定义的类型(类,结构体等)。在运行中必须用实际的数据类型替代它
4、template 语句 和 函数模板定义语句不允许有别的语句
如:
template <class T>
int i; //这是不允许的.
T max(T a , T b)
{
return (a>b)?a:b;
}
举例:求两个数最大值,使用模板
template <class T>
T max(T a , T b)
{
return (a>b)?a:b;
}
调用:
int i1,i2;
flaot f1,f2;
max(i1,i2);
max(f1,f2);
运行过程可分两部分:
第一、传递参数类型:用模板实参int将 类型参数T进行实例化。即用 int 代替T
第二、传递参数:把参数传递给函数
函数模板的重载:
引入函数模板重载的原因:函数模板要求要传入参数类型必须全都相同,不同则报错。使用函数模板重载就是要解决这个问题
引入两种方法解决这个问题:
1、函数模板可以使用多个模板参数:有几个不同的类型,就是用不同的模板参数来代表它。
2、超载一个函数模板:定义一个模板后,在定义一个超载函数
具体来说:
1、定义一个多参的函数模板:
template <class T,class D>
T max(T a,D b)
{
return (a>b)?a:b;
}
调用:
int a;float b;
max(a,b)
2、超载一个函数模板
template <class T>
T max(T a,T b)
{
return (a>b)?a:b;
}
int max(int,int);//用户自己定义一个同名函数
参数调用:int m,n;
char a,b;
char s[10];
max(m,n);//调用函数 实参和函数的参数类型完全一致,直接调用函数
max(a,b);//调用模板 实参和函数参数类型不同,直接掉模板
max(m,a);//调用函数 实参的类型不同,模板不适合,则再次调用函数
max(m,s);//报错-函数也不适合,直接报错
分析:调用函数时的顺序:先调用函数 --- 其次套用模板 --- 再调用函数 --- 报错
运行步骤:
如果调用语句的实参类型和函数类型完全一致,这时不找模板,而优先使用函数。
如果调用语句的实参类型和函数类型不一致,应该找模板
如果调用语句的实参各自类型不同,应重新调用函数,并试着把实参类型转换为形参类型,成功则调用,失败,则报错
函数模板和类结合
举例:
#include <iostream>
using namespace std;
class Point
{
private:
int x;
public:
Point(int x1);
bool operator>(const Point& p);
friend ostream& operator<<(ostream& cout,const Point& p);
};
Point::Point(int x1)
{
x=x1;
}
bool Point::operator>(const Point& p)
{
return (x>p.x)?true:false;
}
ostream& operator<<(ostream& cout,const Point& p)
{
cout<<p.x;
return cout;
}
template <class T>
T& max(T& a,T& b)
{
cout<<"调用函数模板"<<endl;
return (a>b)?a:b;
}
void main()
{
Point a(1);
Point b(2);
cout<<max(a,b);
system("pause");
}
什么时候使用模板:
1、创建一个类型安全的集合类(如,堆栈)用来处理各种类型的数据
2、为函数添加额外的类型检查以避免获得空指针
模板的优势:为函数大多数以上应用可以不用模板实现
模板具有以下几个优势:
1、开发容易。你可以只为你的类或函数创建一个普通的版本代替手工创建特殊情况处理。
2、理解容易。模板为抽象类型信息提供了一个直截了当的方法。
3、类型安全。模板使用的类型在编译时是明确的,编译器可以在发生错误之前进行类型检查。
C++ 函数模板基础知识的更多相关文章
- C++ 类模板基础知识
类模板与模板类 为什么要引入类模板:类模板是对一批仅仅成员数据类型不同的类的抽象,程序员只要为这一批类所组成的整个类家族创建一个类模板,给出一套程序代码,就可以用来生成多种具体的类,(这类可以看作是类 ...
- Django模板-基础知识
上一篇中带参数的URLconf虽然可以做到传参动态显示内容,但是最终现实的内容还是硬编码到Python代码中的 def hours_ahead(request,phours): try: phours ...
- JS中函数的基础知识
函数 一. 函数定义 函数又叫方法,在程序里面函数是用来执行某些特定功能的代码.为了减少重复使用代码,可以把特定功能的代码做成函数,需要使用时拿出来调用.alert();就是一个很常见的.简单的函数 ...
- smarty模板基础知识
1.定义 Smarty是一个使用php写出来的模板引擎,它分离了逻辑代码和外在的内容,提供了一种易于管理和使用的方法,用来将原本与html代码混杂在一起PHP代码逻辑分离. 简单的讲,目的就是要使PH ...
- python学习9 函数的基础知识
1.函数的定义 def func(): 2.函数的调用 func() 3.函数的返回值 #1.没有返回值 # (1)不写return # (2)只写return后面的代码不在继续执行,返回空,代表结 ...
- javascript 函数的基础知识
1. Why JavaScript functions always return a value? I'm taking a course in JavaScript programming, an ...
- [转]C++函数模板与模板函数
1.函数模板的声明和模板函数的生成 1.1函数模板的声明 函数模板可以用来创建一个通用的函数,以支持多种不同的形参,避免重载函数的函数体重复设计.它的最大特点是把函数使用的数据类型作为参数. ...
- Python基础知识详解 从入门到精通(七)类与对象
本篇主要是介绍python,内容可先看目录其他基础知识详解,欢迎查看本人的其他文章Python基础知识详解 从入门到精通(一)介绍Python基础知识详解 从入门到精通(二)基础Python基础知识详 ...
- Greenplum入门——基础知识、安装、常用函数
Greenplum入门——基础知识.安装.常用函数 2017年10月08日 22:03:09 在咖啡里溺水的鱼 阅读数:8709 版权声明:本文为博主原创,允许非商业性质转载但请注明原作者和出处 ...
随机推荐
- MariaDB基于GTID主从复制及多主复制
一.简单主从模式配置步骤(必须要mysql5.6,此处以maridb10.0.10为例) 1.配置主从节点的服务配置文件 # vim /etc/my.cnf 1.1.配置master节点: [mysq ...
- Http请求中请求头Content-Type讲解
在Http请求中,我们每天都在使用Content-type来指定不同格式的请求信息,但是却很少有人去全面了解content-type中允许的值有多少,这里将讲解Content-Type的可用值 Med ...
- STM32应用实例六:与MS5837压力传感器的I2C通讯
MS5837压力传感器是一种可用于电路板上,适用于检测10-1200mbar压力范围的传感器,灵敏度非常高,理论上能够检测到0.01mbar的压力变化,实际使用过程中测试并无明显的变化. MS5837 ...
- Linux VMware tools安装步骤
Linux VMware tools安装步骤: 1.安装环境介绍 #虚拟机版本:VMware-workstation-full-10 #linux分发版本:CentOS-6.4-i386-LiveCD ...
- java多线程快速入门(七)
什么是守护线程 守护线程是为用户线程服务的这么一个线程,主线程结束,守护线程也结束 package com.cppdy; class MyThread3 extends Thread{ @Overri ...
- php实现概率性随机抽奖代码
1.初始数据: 权重越大,抽取的几率越高 [奖品1, 权重 5], [ 奖品2, 权重6], [ 奖品3, 权重 7], [ 奖品4, 权重2] 2.处理步骤: 1)N = 5 + 6 + 7 + 2 ...
- openj 4004 01背包问题求方案数
#include<iostream> #include<cstring> #include<cstdio> using namespace std; #define ...
- kafka删除topic数据
一.概述 生产环境中,有一个topic的数据量非常大.这些数据不是非常重要,需要定期清理. 要求:默认保持24小时,某些topic 需要保留2小时或者6小时 二.清除方式 主要有3个: 1. 基于时间 ...
- Windows C#入门环境搭建
Windows C#入门环境搭建 1. 安装Microsoft .NET Framework目录: C:\Windows\Microsoft.NET\Framework,查看已经安装的版本. 如果未安 ...
- 《SQL基础教程》
Product表 CREATE TABLE Product (product_id CHAR(4) NOT NULL, product_name VARCHAR(100) NOT NULL, prod ...