什么是函数模板
实际上是一种通用函数,其函数类型和参数类型不具体指定,用一个虚拟的类型来表示。这样的通用函数就是函数模板。
凡是函数体相同的函数都可以用这个模板来代替,不必定义多个函数,只需要在模板中定义一次即可。在调用函数时系统会根据调用的实参类型来取代模板中的虚拟类型,从而实现不同函数的功能。
本质:类型参数化
为什么要有函数模板
当开发中当存在功能相同,不需要重复修改业务逻辑时,函数模板可以减少相同代码的重复编写,提高效率。例如:写n个函数,交换char类型、int类型、double类型变量的值。
函数模板声明
template <类型形式参数表>
类型 函数名 (形参列表) { }
#pragma warning(disable : 4996)
#include <iostream>
using namespace std;
template <typename T>
void Swap(T &a,T &b)
{
T temp = a;
a = b;
b = temp;
}
int main()
{
int a = 10;
int b = 20;
Swap<int>(a, b);
Swap(a, b);
cout << "a = " << a << "b = " << b << endl;
system("pause");
return 0;
}
函数模板的调用:
Swap<int>(a, b); //显示类型调用
Swap(a, b); //自动数据类型推导
- 函数模板定义由模板说明和函数定义说明
- 模板说明的类属参数必须在函数定义中至少出现一次
- 函数参数中可以使用类属类型参数,也可以使用一般类型参数
- 模板类中如果有构造函数,和一般类的构造函数调用规则一样
类属——模板把函数或类要处理的数据类型参数化,表现为参数的多态性,称为类属。
#include <iostream>
using namespace std;
//相同参数类型
template <typename T>
///交换位置
void MySwap(T &a,T &b)
{
T c = NULL;
c = a;
a = b;
b = c;
}
//不同参数类型
template <typename T,typename T1>
///排序
void MySort(T *array,T1 size)
{
T1 i, j;
T temp = 0;
for (i = 0; i < size;i++)
{
for (j = i+1; j<size;j++)
{
if (array[i] < array[j])
{
temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
}
//不同参数类型
template <typename T,typename T1>
void MyPrint(T *array,T1 size)
{
for (int i = 0; i < size; i++)
{
cout << array[i] << " ";
}
}
int main()
{
int a = 10;
int b = 20;
MySwap<int>(a, b);// 显示类型调用
MySwap(a, b);//自动类型数据推导
printf("a:%d,b:%d \n", a, b);
char c = 'c';
char d = 'd';
MySwap<char>(c, d);//显示类型调用
MySwap(c, d);//自动类型数据推导
printf("c:%c,d:%c \n", c, d);
int array[] = { 5,34,23,76,23,4,5,0,9,12,2,33 };
int size = sizeof(array) / sizeof(*array);
MySort<int,int>(array, size);// 显示类型调用
MyPrint(array, size);//自动类型数据推导
cout << endl;
char cArray[] = "ashjku3256yiuuh";
int len = strlen(cArray);
MySort(cArray, len);
MyPrint(cArray, len);
system("pause");
return 0;
}
函数模板和函数重载
- 函数模板可以像普通函数一样被重载
- C++编译器优先考虑普通函数
- 如果函数模板可以产生一个更好的匹配,那么选择模板
- 可以通过空模板实参列表的语法限定编译器只通过模板匹配
#pragma warning(disable : 4996)
#include <iostream>
using namespace std;
int Max(int a, int b)
{
cout << "普通函数" << endl;
return a < b ? b : a;
}
template <typename T>
T Max(T a, T b)
{
cout << "模板函数" << endl;
return a < b ? b : a;
}
template <typename T>
T Max(T a, T b, T c)
{
cout << "模板函数" << endl;
return Max(Max(a, b), c);
}
int main()
{
int a = 10;
int b = 20;
char c = 'w';
//当函数模板和普通函数都符合调用时,优先调用普通函数
cout << Max(a, b) << endl;
//如显示使用函数模板,则使用<>类型列表
cout << Max<>(a, b) << endl;
//如果函数模板产生更好的匹配 使用函数模板
cout << Max(2.0, 5.0) << endl;
//重载
cout << Max(1.0, 3.0, 4.0) << endl;
//调用普通函数 隐式类型转换
cout << Max(a, c) << endl;
system("pause");
return 0;
}
template <typename T>
void myswap(T &a, T &b)
void myswap(char &a, int &b)
函数模板和普通函数区别:
函数模板不提供隐式的数据类型转换 必须是严格的匹配
普通函数能够进行自动类型转换