C++:函数模板、类模板及其特化

来源:互联网 发布:阿里云os root 编辑:程序博客网 时间:2024/05/15 23:50

模板分为函数模板和类模板。下面我们先来介绍函数模板.
1,函数模板:该函数与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型。
我们距离来说明函数模板的具体用法。
定义一个实现加法功能的函数模板:

template <typename T>//模板参数列表T Add(T left,T right)//函数模板{  return left+right;}

模板函数也可以定义为内联函数,不过要注意inline只能放在模板参数列表之后,返回值之前。如:

templete <typename T>inline T Add(T left,T right>{  return left+right;}

模板本身不是类或者函数,编译器用模板产生特定类型的类或函数,产生特定类型的过程,称为模板函数实例化。

template<typename T>T Add(T left, T right){    cout << typeid(left).name()<<":";    return left + right;}int Add(int left, int right){    return left + right;}int main(){    cout << Add<>(2, 3) << endl << endl;//隐式调用模板类型的int    cout << Add(1.5, 2.6) << endl << endl;    cout << Add(1,(int)2.5) << endl << endl;//显式类型转换,调用显式给出的int型    system("pause\n");    return 0;}

执行结果为:
这里写图片描述
程序执行过程中,模板被编译了两次。
(1)在模板实例化之前,检查模板本身是否出现语法错误
(2)在实例化期间。检查模板代码,看是否所有函数调用都有效。

这里写图片描述

模板形参名字只能在模板形参之后到模板声明或定义的末尾之间使用,遵循名字屏蔽规则。
这里写图片描述
注意:
这里写图片描述

模板非类型形参:表示一个固定类型的常量而不是一个类型。只有整型,指针,引用才能作为非类型形参,而且绑定到该形参的实参必须是常量表达式。

这里写图片描述

下面介绍类型形参的转换:
编译器只会执行两种转换
(1)const转换:接收const引用或const指针的函数可以分别用非const指针的函数或者指针来调用,不需要产生新的实例化。如果函数接收非引用类型,形参和实参都忽略const,即,无论传递const或非const对象给接受非引用类型的函数,都使用相同的实例化。
(2)数组或函数到指针的转换:如果模板形参不是引用类型。则对数组或数组类型的实参应用常规指针转换。数组实参将当做其指向第一个元素的指针,函数实参当做指向函数类型的指针。
举例说明:

template <class T>const T& Max(const T& left, const T& right){    return (left > right) ? left : right;}int main(){    int ret = Max(22, 50);    system("pause\n");    return 0;}

我们来看看调试过程:
这里写图片描述

注意到,const int& 转换为int型

模板函数特化
有时候,通用模板定义函数可能对某些类型是错误的或者不能编译,这时候就需要进行函数模板特化。我们先来看一个反例:
这里写图片描述
本应该输出1,结果却是-1。这是因为这里本应比较两个字符串的大小,编译器却只比较了两个指针的地址大小。
如果再加上如下函数的定义:

template<>int Compare<const char*>(const char* const p1,const char* const p2){  return strcpy(p1,p2);}

我们再来看结果:
这里写图片描述

以上介绍的就是模板的特化。

下面介绍模板类
类模板也是模板,所以同样需要template<>。

template<typename T1,typename T2>class Test//类模板{public:    Test(T1 i, T2 j)        :a(i), b(j)    {        cout << "模板类" << endl;    }private:    T1 a;    T2 b;};template<>//全特化class Test<int, char>{public:    Test(int i, char j)        :a(i), b(j)    {        cout << "全特化" << endl;    }    int a;    char b;};template<typename T2>//偏特化class Test<char, T2>{public:    Test(char i, T2 j)        :a(i), b(j)    {        cout << "半特化" << endl;    }    char a;    T2 b;};int main(){    Test<double, double>t1(0.1, 0.2);    Test<int, char>t2(1, 'a');    Test<char, bool>t3('A', true);    system("pause\n");    return 0;}

打印结果如下:
这里写图片描述

1 0
原创粉丝点击