C++提供了函数模板(function template)。所谓函数模板,实际上是建立一个通用函数,其函数类型和形参类型不具体指定,用一个虚拟的类型来代表。这个通用函数就称为函数模板。凡是函数体相同的函数都可以用这个模板来代替,不必定义多个函数,只需在模板中定义一次即可。在调用函数时系统会根据实参的类型来取代模板中的虚拟类型,从而实现了不同函数的功能。
函数模板定义形式
template < 类型形式参数表 >
类型形式参数的形式为:
typename T1 , typename T2 , …… , typename Tn
或 class T1 , class T2 , …… , class Tn
myswap< float >(a, b); //显示类型调用
myswap(a, b); //自动数据类型推导
函数模板遇上函数重载
函数模板和普通函数区别:
函数模板不允许自动类型转化
普通函数能够进行自动类型转换
函数模板和普通函数在一起调用规则:
1 函数模板可以像普通函数一样被重载
2 C++编译器优先考虑普通函数
3 如果函数模板可以产生一个更好的匹配,那么选择模板
4 可以通过空模板实参列表的语法限定编译器只通过模板匹配
函数模板机制
编译器并不是把函数模板处理成能够处理任意类的函数
编译器从函数模板通过具体类型产生不同的函数
编译器会对函数模板进行两次编译
在声明的地方对模板代码本身进行编译;在调用的地方对参数替换后的代码进行编译。
#include <iostream>
using namespace std;
// 写函数来 交换两个 int char double 变量
void Swap(int &a, int &b)
{
int tmp = a;
a = b;
b = tmp;
}
void Swap(char &a, char &b)
{
char tmp = a;
a = b;
b = tmp;
}
void Swap(double &a, double &b)
{
double tmp = a;
a = b;
b = tmp;
}
// 函数重载: 函数名相同,通过不同的调用实现不同的功能
// 函数三要素:返回值 函数名 函数的参数列表 函数体
// 函数的参数构成:类型 变量(存的是值)
// 函数调用:实参 -----> 形参 将变量的值当参数进行传递
// 问题:函数的类型能否当参数进行传递? 能 -----> 函数模板
// 函数模板定义:用 template 将函数声明成函数模板
template <typename T>
void mySwap(T &a, T &b)
{
T tmp = a;
a = b;
b = tmp;
}
template <typename T>
void myPrint(T a, T b)
{
cout << "a = " << a << ", b = " << b << endl;
}
int main()
{
int a = 10;
int b = 20;
mySwap(a, b); // 可以隐式调用 函数模板 编译器会自己判断变量的类型
// cout << "a = " << a << ", b = " << b << endl;
myPrint(a, b);
// 变量类型进行参数化:如何传类型?
mySwap<int>(a, b);
// cout << "a = " << a << ", b = " << b << endl;
myPrint<int>(a, b);
char c1 = 'a';
char c2 = 'b';
mySwap<char>(c1, c2);
// cout << "a = " << c1 << ", b = " << c2 << endl;
myPrint<char>(c1, c2);
double d1 = 1.2;
double d2 = 2.3;
mySwap<double>(d1, d2);
// cout << "a = " << d1 << ", b = " << d2 << endl;
myPrint<double>(d1, d2);
return 0;
}