本文章将对模板函数的相关内容进行说明,如有不足,欢迎指正。
函数模板的知识点可以分为以下几点:
1. 函数模板
2. 函数模板的作用域
3. 函数模板的显式隐式实例化
4. 函数模板的重载
5. 非模板函数
函数模板具有以下特征:
1. 函数模板本身不进行编译,实例化出的函数代码则要进行编译
2. 函数模板类型自推,能够根据参数类型自动推演出模板类型
3. 编译时期根据模板调用的类型方式,自动生成一份对应于该类型的代码(模板的实例化)
4.模板的作用域只在当前文件,通过引用其他文件的头文件与声明也无法编译
5.函数调用的优先级:非模板函数->特例化函数->模板函数
注:
#define char* CharPtr 字符替换,不进行类型检查
typedef char* CharPtr; 重命名数据类型
const CharPtr a; 字符替换,const修饰的是char
详细内容请看以下相关代码
代码示例1:
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
/*函数模板的显式实例化
template bool compare<int>(int a, int b);
template bool compare<double>(double a, double b);
*/
//T是一种类型
//函数模板的隐式实例化
/*
template<typename T>
bool compare(T a, T b)
{
cout<<"bool compare(T a, T b)"<<typeid(T).name()<<endl;
return a>b;
}
*/
//函数模板
template<typename T>
bool compare(const T a, const T b)
{
cout<<"bool compare(const T a, const T b)"<<typeid(T).name()<<endl;
return a > b;
}
//函数,模板的特例化
typedef char* CharPtr;
template<>
bool compare<CharPtr>(const CharPtr a, const CharPtr b)
{
cout<<"bool compare<CharPtr>(const CharPtr a, const CharPtr b)"<<endl;
return strcmp(a, b) > 0;
}
//非模板函数
bool compare(const double a, const double b)
{
cout<<"bool compare(const double a, const double b)"<<endl;
return a > b;
}
/*
//函数模板的特例化 error,正确的做法是将char*替换成CharPtr,这样const修饰的就为char*整体了
template<>
bool compare<const char*>(const char* a, const char* b)//const修饰的是char
{
cout<<"bool compare<const char*>(const char* a, const char* b)"<<endl;
return strcmp(a, b) > 0;
}
*/
//模板函数的重载,实现数组的比较
template<typename T>
bool compare(T* arr1, int len1, T* arr2, int len2)
{
cout<<"bool compare(T* arr1, int len1, T* arr2, int len2)"<<typeid(arr1).name()<<endl;
int i, j;
for(i=0,j=0; i<len1&&j<len2; i++,j++)
{
if(arr1[i] > arr2[j])
{
return true;
}
}
if(i == len1) //arr1 < arr2
{
return false;
}
return true;
}
int main()
{
int a = 10;
int b = 20;
compare<int>(a, b);//模板函数
compare(10.2, 13.2);//非模板函数
compare<char *>("hello", "world");//模板函数特例化
compare("hello", 5, "world", 5); //模板函数的重载
return 0;
}
代码示例2:
#include <iostream>
#include <string.h>
#include <stdlib.h> //产生随机数的头文件
#include <time.h>
using namespace std;
//1模板函数
//冒泡排序
template<typename T>
void boobleSort(T arr[], int len)
{
int i,j;
T tmp;
for(i=0; i<len; i++)
{
for(j=i; j<len; j++)
{
if(arr[i] < arr[j]) //由大到小排序
{
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
}
}
//2模板函数特例化实现冒泡排序
//字符串类型的冒泡排序
template<>
void boobleSort<char*>(char* arr[], int len)
{
int i,j;
char* tmp;
for(i=0; i<len; i++)
{
for(j=i; j<len; j++)
{
if(strcmp(arr[i],arr[j]) < 0) //若前面的数小于后面的数
{
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
}
}
//1实现比较的模板函数
template<typename T>
bool myLess(T a, T b)
{
cout<<"bool myless(T a, T b)"<<endl;
return a < b;
}
//2实现比较的模板函数特例化
template<>
bool myLess<char*>(char* a, char* b)
{
cout<<"bool myLess<char*>(char* a, char* b)"<<endl;
return strcmp(a, b) < 0;
}
//用冒泡法对数组内元素排序
//模板函数
template<typename T, int len>
void boobleSort(T arr[])
{
cout<<"void boobleSort(T arr[])"<<typeid(T).name()<<endl;
int i,j;
T tmp;
for(i=0; i<len; i++)
{
for(j=i; j<len; j++)
{
if(myLess(arr[i], arr[j])) //由大到小排序
{
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
}
}
//模板函数的比较器,可比较大于小于
template<typename T, int len, typename PRE>
void boobleSort(T arr[], int len, PRE pre)
{
cout<<"void boobleSort(T arr[], int len, PRE pre)"<<typeid(T).name()<<endl;
int i, j;
T tmp;
for(i=0; i<len; i++)
{
for(j=i; j<len; j++)
{
if(pre(arr[i], arr[j]))
{
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
}
}
int main()
{
int i;
srand(time(0)); //产生随机数种子
int arr[10] = {0};
for(i=0; i<10; i++)
{
arr[i] = rand() % 100 + 1; //产生100以内的随机数
}
/*//模板函数的测试
boobleSort<int, 10>(arr);
for(i=0; i<10; i++)
{
cout<<arr[i]<<" ";
}
cout<<endl;
*/
//模板函数特例化的测试
char* arr1[] = {"abc","opq","xyz"};
boobleSort<char*,3>(arr1);
for(i=0; i<3; i++)
{
cout<<arr1[i]<<" ";
}
cout<<endl;
return 0;
}
代码示例3(对示例2的改进与简化版):
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
//模板函数
template<typename T>
bool Myless(T a,T b)
{
return a < b;
}
//模板的特例化
template<>
bool Myless<char*>(char* a, char* b)
{
return strcmp(a,b) < 0;
}
//模板函数
template<typename T>
bool Mygreater(T a,T b)
{
return a > b;
}
//模板的特例化
template<>
bool Mygreater<char*>(char* a, char* b)
{
return strcmp(a, b) > 0;
}
//类型作为模板类型参数
template<typename T, typename PRE>
void Msort(T *arr, int len, PRE pre)
{
T tmp;
for(int i=0; i<len; i++)
{
for(int j=i+1; j<len; j++)
{
//if(arr[i] > arr[j])//由小到大
//if(arr[i] < arr[j])//由大到小
//if(Mygreater(arr[i], arr[j]))
//if(Myless(arr[i], arr[j]))
if(pre(arr[i], arr[j]))
{
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
}
}
int main()
{
srand(time(0));
int arr[10] = {0};
for(int i=0; i<10; i++)
{
arr[i] = rand()%100+1;
}
Msort(arr,10,Myless<int>);
for(int i=0; i<10; i++)
{
cout<<arr[i]<<" ";
}
cout<<endl;
return 0;
}