28、C++类模板的特化
来源:互联网 发布:泸州市网络春晚酒文化 编辑:程序博客网 时间:2024/05/31 19:38
C++类模板的特化
有的时候某些类型不能直接用来实例化类模板,或者说直接实例化不能满足需要,
此时就要针对这种类型进行特化,包括特化(即全特化)和偏特化。
1、特化为绝对类型
目的:为了针对特殊的类型进行特殊处理,重新修改成新的逻辑,定义一个
新的特化的类模板。
特点:template后没有形参说明,类模板名加了模板实参列表。
基本语法:
template<>
class 类模板名<模板实参列表>
{
新的逻辑操作
};
2、偏特化(部分特化)
给出部分实参。仍有个别参数没有给出实际参数。
特点:template后的模板形参的形参没有全部不写,类模板名后添加了参数说明。
或者两个都
基本语法:
template<模板形参列表>
class 类模板名<模板形参表>
{
};
注:类模板名后的形参,可以把template后的形参当作已知的类型,组合成新
的类型来作为类模板的参数。然后通过实例化template的形参,
最后进一步确定类模板的实参。
注:所有特化类模板之前,一定先需要定义同名的非特化类模板,否则会有编译错误
注:所有特化模板的形参以跟着类模板名后面的 < >为标准,而非特化模板以跟着
template后面的< >为标准。进行参数赋值。
一、全特化
测试程序
#include <iostream>using namespace std;//类模板的特化之全特化//普通非特化类模板template <typename T,int size>class Vector{private : T arr_data[size];public: Vector(T *data) { for(int i=0;i<size;i++) { arr_data[i] = *(data+i); } } T Sum();};template <typename T,int size>T Vector<T,size>::Sum(){ cout<<"调用非特化类模板实例的Sum函数!"<<endl; T sumvalue=0; for(int i=0;i<size;i++) { sumvalue+=*(arr_data+i); } return sumvalue;}//全特化类模板template <>class Vector<int,1>{private: int data;public: Vector(int d); int Sum();};//全特化的函数在在类外定义,不需要加上 template < >Vector<int,1>::Vector(int d):data(d){}int Vector<int,1>::Sum(){ cout<<"调用全特化类模板Vector<int,1>的函数Sum"<<endl; return data;}int main(){ int int_arry[10]={1,2,3,4,5,6,7,8,9,10}; float float_arry[10]={2,3,4,5,6,7,8,9,10,11.0}; int i1=100; Vector<int,10> int_vector(int_arry); Vector<float ,10> float_vector(float_arry); Vector<int,1> int1(i1); cout<<int_vector.Sum()<<endl; cout<<float_vector.Sum()<<endl; cout<<int1.Sum()<<endl; return 0;}
输出结果:
调用非特化类模板实例的Sum函数!
55
调用非特化类模板实例的Sum函数!
65
调用全特化类模板Vector<int,1>的函数Sum
100
Process returned 0 (0x0) execution time : 0.130 s
Press any key to continue.
二、部分特化之普通特化
测试程序:
#include <iostream>#include <cstring>using namespace std;//类模板的特化//普通的非特化类模板template <typename T,int size>class Vector{ private: T arr_data[size]; public: Vector(T *data ) { for(int i=0;i<size;i++) { arr_data[i]=data[i]; } } T Sum();};template <typename T,int size>T Vector<T,size>::Sum(){ T sumvalue=0; cout<<"调用非特化类模板实例中的函数!"<<endl; for(int i=0;i<size;i++) { sumvalue+=arr_data[i]; } return sumvalue;}//这样的求和,如果是针对INT float型都适合,可是针对字符数组就不行。//普通的部分特化template <int size> //只有一个参数被给了实参。class Vector<char ,size>{ private: char arr_data[size+1]; public: Vector(char *data ) { strcpy(arr_data,data); } char * Sum();};template <int size>char * Vector<char,size>::Sum(){ cout<<"调用部分特化类模板Vector<char,size>中的sum函数!"<<endl; char * c_arry=new char[size+1]; strcpy(c_arry,arr_data); return c_arry;}int main(){ int int_array[10]={1,2,3,4,5,6,7,8,9,10}; float float_array[10]={2,3,4,5,6,7,8,9,10.0,11.0}; char c_array[10]="ABCDEFG"; const int c_size=sizeof(c_array); //这里如果使用strlen就不可以出现在模板实参中,因为sizeof()编译时处理的。strlen是函数,运行时决定, //int size 实参要求必须是编译时就能决定出来的常量表达式 Vector<int,10> int_vector(int_array); Vector<float,10> float_vector(float_array); Vector<char,c_size> char_vector(c_array);//这里的实例化,也必须是两个参数, cout<<int_vector.Sum()<<endl; cout<<float_vector.Sum()<<endl; cout<<char_vector.Sum()<<endl; return 0;}
输出结果:
调用非特化类模板实例中的函数!
55
调用非特化类模板实例中的函数!
65
调用部分特化类模板Vector<char,size>中的sum函数!
ABCDEFG
三、部分特化之引用与指针
测试程序:
#include <iostream>using namespace std;//类模板的特化template <typename T,typename U>class Ctest{public: void f();};template <typename T,typename U>void Ctest<T,U>::f(){ cout<<"调用非特化类模板实例对象的函数"<<endl;}//偏特化为引用template <typename T,typename U>class Ctest<T &,U &>{public: void f();};template <typename T,typename U>void Ctest<T &,U &>::f(){ cout<<"调用偏特化为引用的类模板实例对象的函数"<<endl;}//偏特化为指针 第二个参数是inttemplate <typename T>class Ctest<T *,int>{public: void f();};template <typename T>void Ctest<T *,int>::f(){ cout<<"调用偏特化为指针,第二个参数是int的类模板实例对象的函数"<<endl;}int main(){ //只用完全符合特化模板形参的才会调用特化模板,只要不符合的调用的全都是非特化模板。 Ctest<int,int> in_c; in_c.f(); Ctest<int &,int &> in_c1; in_c1.f(); Ctest<int *,int &> in_c2; in_c2.f(); Ctest<int *,int> in_c3; in_c3.f(); return 0;}
输出结果:
调用非特化类模板实例对象的函数
调用偏特化为引用的类模板实例对象的函数
调用非特化类模板实例对象的函数
调用偏特化为指针,第二个参数是int的类模板实例对象的函数
Process returned 0 (0x0) execution time : 1.451 s
Press any key to continue.
四、部分特化之类模板
测试程序:
Vector.h
#include <iostream>using namespace std;//类模板的特化之全特化//普通非特化类模板template <typename T,int size>class Vector{private : T arr_data[size];public: Vector(T *data) { for(int i=0;i<size;i++) { arr_data[i] = *(data+i); } } T Sum();};template <typename T,int size>T Vector<T,size>::Sum(){ cout<<"Vector调用非特化类模板实例的Sum函数!"<<endl; T sumvalue=0; for(int i=0;i<size;i++) { sumvalue+=*(arr_data+i); } return sumvalue;}//全特化类模板template <>class Vector<int,1>{private: int data;public: Vector(int d); int Sum();};//全特化的函数在在类外定义,不需要加上 template < >Vector<int,1>::Vector(int d):data(d){}int Vector<int,1>::Sum(){ cout<<"Vector调用全特化类模板Vector<int,1>的函数Sum"<<endl; return data;}
main.cpp
#include <iostream>#include "Vector.h"//包含我们自定义的类模板头文件using namespace std;//类模板的特化之特化为另一个类模板template <typename T,int size>class Ctest{public: void f();};template <typename T,int size>void Ctest<T,size>::f(){ cout<<"Ctest调用非特化类模板实例对象的函数"<<endl;}template <typename T,int size>class Ctest< Vector<T,size>,size>{public: void f();};template <typename T,int size>void Ctest<Vector<T,size>,size>::f(){ cout<<"Ctest调用特化为Vector类模板的函数"<<endl;}int main(){ //Vector的参数我们并不关心特化和非特化,而由Vector.h文件中的内容决定。 //非特化模板 以跟着template后的< 参数列表> 为标准进行参数赋值 Ctest<int,10> c001; c001.f(); //特化模板 以跟着类模板名后的< 参数列表> 为标准进行参数赋值 Ctest<Vector<int,10>,10> c002; c002.f(); return 0;}
输出结果:
Ctest调用非特化类模板实例对象的函数
Ctest调用特化为Vector类模板的函数
Process returned 0 (0x0) execution time : 1.685 s
Press any key to continue.
- 【c++】模板的特化
- 【C++】模板类、特化以及偏特化!!!
- 类模板的特化
- 类模板的特化
- 类模板的特化和偏特化
- 类模板的 全特化、偏特化
- 类模板的特化,偏特化
- 28、C++类模板的特化
- C++:函数模板、类模板及其特化
- C++类模板的特化
- C++ 类模板的特化
- 类模板的偏特化
- C++类模板的特化
- C++模板的特化
- C++模板的特化
- 模板的特化、偏特化
- 模板的特化与偏特化 ,C++类模板的三种特化
- 类模板的全特化和偏特化
- mfc键盘消息总结以及键值表
- jQuery Mobile 1.3.0发布
- ssis package 从sql 2005升级到sql 2008的方法
- 3D model study
- 【Notepad++】 配置
- 28、C++类模板的特化
- 用Blender导出模型文件,与贴图制作
- [转]七大毛病成为开发人员前行的绊脚石
- java_对一些容易混淆关键词的理解
- javascript 数组
- opencv之运动目标动作分割
- pager优化
- git add详解
- struct2的类型转换