C++笔记-25-函数模板

模板的概念

模板就是建立通用的模具,大大提高复用性

例如生活中的证件照,就可以找一个通用的蓝底,红底图片,把自己的图片给P上去。那么这个通用的图片,就叫一个模板。

函数模板

C++另一种编程思想称为泛型编程,主要利用的技术就是模板

C++提供两种模板机制:函数模板和类模板

函数模板作用:建立一个通用函数,其函数返回值类型和形参类型可以不具体制定,用一个虚拟的类型来代表。

语法:
template<typename T>
函数声明或定义

解释:

template:声明创建模板

typename:表面其后面的符号是一种数据类型,可以用class代替

T:通用的数据类型,名称可以替换,通常为大写字母

cpp 复制代码
#include<iostream>
using namespace std;
template<typename T>
void myswap(T& a, T& b)
{
	T temp = a;
	a = b;
	b = temp;
}
void test()
{
	int a = 10;
	int b = 20;
	//1.自动类型推导
	//myswap(a, b);
	//2.显示指定类型
	myswap<int>(a, b);
	cout << a << endl;
	cout << b << endl;

}
int main()
{
	test();
}

例如实现两个数交换的功能,可能会有两个int型交换,两个double型交换等等,那么就要写很多个函数,但是我们使用函数模板,一个函数就可以解决了。

总结:

  • 函数模板利用关键字template
  • 使用函数模板有两种方式:自动类型推导、显示指定类型·-
  • 模板的目的是为了提高复用性,将类型参数化

函数模板的注意事项

注意事项:

  • 自动类型推导,必须推导出一致的数据类型T,才可以使用
  • 模板必须要确定出T的数据类型,才可以使用
cpp 复制代码
#include<iostream>
using namespace std;
template<class T>
void myswap(T& a, T& b)
{
	T temp = a;
	a = b;
	b = temp;
}
void test()
{
	int a = 10;
	int b = 20;
	char c = 'a';
	myswap(a, b);
	cout << a << endl;
	cout << b << endl;
	//myswap(a, c);错误,推导出不一致的T类型
}
template<class T>
void func()
{
	cout << "func的调用" << endl;
}
void test01()
{
	//没有传入任何参数,无法自动推导出数据类型,会报错
	//必须显示指定一个类型,就可以正常使用了。
	func<int>();
}
int main()
{
	/*test();*/
	test01();
}

总结:

使用模板时必须确定出通用数据类型T,并且能够推导出一致的类型

普通函数和函数模板的区别

普通函数与函数模板区别:

  • 普通函数调用时可以发生自动类型转换(隐式类型转换)
  • 函数模板调用时,如果利用自动类型推导,不会发生隐式类型转换·
  • 如果利用显示指定类型的方式,可以发生隐式类型转换
cpp 复制代码
#include<iostream>
using namespace std;
int myadd1(int a, int b)
{
	return a + b;
}
void test()
{
	int a = 10;
	int b = 20;
	cout << myadd1(a, b) << endl;
	char c = 'a';
	double d = 25;
	cout << myadd1(c, d) << endl;
}
template<typename T>
T myadd2(T a, T b) {
	return a + b;
}
void test2()
{
	int a = 10, b = 20;
	cout << myadd2(a, b) << endl;
	char c = 'a';
	//cout << myadd2(a, c) << endl;报错,自动类型推导不会发生隐式类型转换
	cout << myadd2<int>(a, c) << endl; //显示指定类型
}
int main()
{
	test2();
}

总结:建议使用显示指定类型的方式,调用函数模板,因为可以自己确定通用类型T

普通函数和模板函数的调用规则

调用规则如下:

  1. 如果函数模板和普通函数都可以实现:优先调用普通函数
  2. 可以通过空模板参数列表来强制调用函数模板
  3. 函数模板也可以发生重载
  4. 如果函数模板可以产生更好的匹配,优先调用函数模板
cpp 复制代码
#include<iostream>
using namespace std;
void myprint(int a, int b)
{
	cout << "调用的普通函数" << endl;
}
template<typename T>
void myprint(T a, T b)
{
	cout << "调用的模板函数" << endl;
}
template<typename T>
void myprint(T a, T b, T c)
{
	cout << "调用的重载模板函数" << endl;
}
void test()
{
	int a = 10, b = 20;
	myprint(10, 20);
	//通过空模板参数列表,强制调用模板函数
	myprint<>(a, b);
	myprint<>(10, 20, 30);
}
void test1()
{
	char c1 = 'a';
	char c2 = 'b';
	myprint(c1, c2);
	//普通的函数定义的int型,而模板函数可以自动推导为char型的,虽然int型的类型转换也能调用,但是char型的更合适。
}
int main()
{
	test1();
}

总结:既然提供了函数模板,最好就不要提供普通函数,否则容易出现二义性

相关推荐
MATLAB代码顾问5 分钟前
混合粒子群-模拟退火算法(HPSO-SA)求解作业车间调度问题——附MATLAB代码
算法·matlab·模拟退火算法
Felven9 分钟前
C. Prefix Min and Suffix Max
算法
加农炮手Jinx9 分钟前
LeetCode 26. Remove Duplicates from Sorted Array 题解
算法·leetcode·力扣
加农炮手Jinx10 分钟前
LeetCode 88. Merge Sorted Array 题解
算法·leetcode·力扣
格林威10 分钟前
线阵工业相机:如何计算线阵相机的行频(Line Rate)?公式+实例
开发语言·人工智能·数码相机·算法·计算机视觉·工业相机·线阵相机
2501_9271682912 分钟前
手机号测吉凶:尾数722手机号吉凶
笔记
yueyue54313 分钟前
透过现象看本质:以fast_lio架构的整套算法的局部避障改为TEB算法为例深度探讨——如何成为一个合格的算法架构师?
算法·架构
梨花爱跨境13 分钟前
红人视频×A10算法:亚马逊转化率与流量闭环实战
算法
近津薪荼14 分钟前
C++ vector容器底层深度剖析与模拟实现
开发语言·c++
广州山泉婚姻16 分钟前
C++ STL Vector 入门与实战全攻略
c语言·c++