例子:
原型:
template <typename AnyType>
void Swap(AnyType& a, AnyType& b);
实现:
template <typename AnyType> //typename可以用class代替,C++98提出使用关键字typename
void Swap(AnyType& a, AnyType& b)
{
AnyType temp;
temp = a;
a = b;
b = temp;
}
//原型
template <typename T>
void Swap(T a, T b,int n);
//实现
template <typename T>
void Swap(T a[], T b[],int n)
{
T temp;
for(int i=0;i<n;i++)
{
temp=a[i];
a[i]=b[i];
b[i]=temp;
}
}
编写的函数模板可能无法处理某些类型
方法:
//level 1:
void Swap(job& ,job&);
//level 2:
template <typename T>
void Swap(T&,T&);
//level 3:
template <>void Swap<job>(job&, job&); //or template <>void Swap(job&, job&);
templat void Swap(int ,int);
Type(argument-list)意味着⽤作实参的函数名与⽤作形 参的函数指针只要返回类型和参数列表相同,就是匹配的。
![image-20211108010839343](C:\Users\ALAN.XUAN\AppData\Roaming\Typora\typora-user-images\image-20211108010839343.png)
- 如果有多个匹配的原型,则编译器将⽆法完成重载解析过程;如果没有最佳的可⾏函数,则编译器将⽣成⼀条错误消息, 该消息可能会使⽤诸如“ambiguous(⼆义性)”这样的词语。
- 有时候,即使两个函数都完全匹配,仍可完成重载解析。
- 指向⾮const数据的指针和引⽤优先与⾮const指针和引⽤参数匹配。
- const和⾮const之 间的区别只适⽤于指针和引⽤指向的数据。
- ⼀个完全匹配优于另⼀个的另⼀种情况是,其中⼀个是⾮模板函 数,⽽另⼀个不是。在这种情况下,⾮模板函数将优先于模板函数(包 括显式具体化)。
- 如果两个完全匹配的函数都是模板函数,则较具体的模板函数优 先。
- 术语“最具体(most specialized)”并不⼀定意味着显式具体化,⽽ 是**指编译器推断使⽤哪种类型时执⾏的转换最少**。
- ⽤于找出最具体的模板的规则被称为函数模板的部分排序规则
```c++
//temptempover.cpp -- template overloading
#include<iostream>
template <typename T>
void ShowArray(T arr[], int n);
template <typename T>
void ShowArray(T* arr[], int n);
struct debts
{
char name[50];
double amount;
};
int main()
{
using namespace std;
int things[6] = { 13,31,103,301,310,130 };
struct debts mr_E[3] =
{
{"jinlin",2400.0},
{"alan",1300.0},
{"xuan",1800.0}
};
double* pd[3];
//设置指针pd指向mr_E的成员
for (int i = 0; i < 3; i++)
{
pd[i] = &mr_E[i].amount;
}
cout << "Listing Mr. E's counts of things:\n";
//things is an array of int
ShowArray(things, 6);
cout << "Listing Mr. E's debts:\n";
//pd is an array of pointers to double
ShowArray(pd, 3);
return 0;
}
template <typename T>
void ShowArray(T arr[], int n)
{
using namespace std;
cout << "template A\n";
for (int i = 0; i < n; i++)
{
cout << arr[i] << ' ';
}
cout << endl;
}
template <typename T>
void ShowArray(T* arr[], int n)
{
using namespace std;
cout << "template B\n";
for (int i = 0; i < n; i++)
{
cout << *arr[i] << ' ';
}
cout << endl;
}
```
输出:
```c++
Listing Mr. E's counts of things:
template A
13 31 103 301 310 130
Listing Mr. E's debts:
template B
2400 1300 1800
```
重载解析将寻找最匹配的函数。
- 如果只存在⼀个这样的 函数,则选择它;
- 如果存在多个这样的函数,但其中只有⼀个是**⾮模板函数**,则选择该函数;
- 如果存在多个适合的函数,且它们都为模板函 数,但其中有⼀个函数⽐其他函数**更具体**,则选择该函数。
- 如果有多个 同样合适的⾮模板函数或模板函数,但没有⼀个函数⽐其他函数更具体,则函数调⽤将是不确定的,因此是错误的;
在有些情况下,可通过编写合适的函数调⽤,引导编译器做出您希望的选择。
示例:
```c++
//choices.cpp -- choosing a template
#include<iostream>
template <class T> //#1
T lesser(T a, T b)
{
return a < b ? a : b;
}
int lesser(int a, int b) //#2
{
a = a < 0 ? -a : a;
b = b < 0 ? -b : b;
return a < b ? a : b;
}
int main()
{
using namespace std;
int m = 20;
int n = -30;
double x = 15.5;
double y = 25.9;
cout << lesser(m, n) << endl; //#2
cout << lesser(x, y) << endl; //#1 with double
cout << lesser<>(m, n) << endl; //#1 with int
//要求进⾏显式实例化(使⽤int替代T),将使⽤显式实例化得到的函数。x和y的值将被强制转换为int,该函数返回⼀个int值,
cout << lesser<int>(x, y) << endl; //#1 with int
return 0;
}
```
输出:
```c++
20
15.5
-30
15
```
- lesser<>(m, n)中的<>指出,编译器应选择模板函数,⽽不是⾮模板 函数;编译器注意到实参的类型为int,因此使⽤int替代T对模板进⾏实 例化。
- 如果函数定义是在使⽤函数前提供的,它将充当函数原型。
编译器必须考虑所有参数的匹配情况
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。