模版编程模版模版函数模版类模版的按需实例化模版的非类型模版参数模版的特化模版的分离编译模版泛型编程的基础编写与数据类型无关的调用代码实现代码复用//关键字templateclassT1,classT2,classT3...templatetypenameT1,typenameT2,typenameT3...模版函数会根据参数类型自动推导出对应函数实例templateclassT1,classT2TAdd(T1a,T2,b)//调用时会根据传参自动推导T的类型{returnab;}但当只有一个模版参数传入参数类型却不同则无法推导出对应类型若想继续使用该模版函数1.对数据进行显示实例化 2.显示实例化int a1;double b2.0;//显示实例化Addint(a,b);Adddouble(a,b);还有一种情况是必须要显示实例化的是当模版参数没有作为函数参数传入时templateclassTT*func(int n)//编译器此时无法推导T的类型{returnnewT[n];}//调用时必须显示实例化funcint(n);模版类模版类都需要显示实例化templateclassTclassA{private:T_a;};//显示实例化Ainta(5);在模版类的使用中往往需要 类名 T 的形式来标识模版类//类外定义成员函数templateclassTvoidStackT::Push(constTn){}//在类外使用模版参数需要先声明模版//模版类作为参数时需要templateTvoidLinkedListT::Push(ListNodeTnode){}注友缘类也需要以 类名 T 形式标识否则被认为是两个不同的类另外在未实例化模版类中通过 类名 T :: 取东西时编译器会无法区分是静态成员在未实例化时静态成员也可以取地址引用等操作还是内部类//typename可以告诉编译器这是一个类型typename vectorT::const_iterator itv.begin();模版的按需实例化在未调用时模版都不会被实例化有些语法错误也不会被编译器检查到例如对const对象进行修改模版的非类型模版参数类型模版参数class T或typename T非类型模版参数一个常量充当模版参数可不带参可带缺省值可做直接参数templatesize_tN10//可带缺省值voidPrint(){coutN;}Print();//可不带参Print5();//带参则覆盖原值模版的特化定义一个适用于特定类型的模版全特化templateclassTvoidPrint(Tt){}template//全特化voidPrint(intt){}半特化/偏特化templateclassT1,classT2voidPrint(T1t1,T2t2){}templateclassT1//偏特化voidPrint(T1t1,intt2){}templateclassT1,classT2//偏特化传入类型为指针voidPrint(T1*t1,T2t2){}//指针和引用可混用//指针偏特化是为了使模版T可以声明其它对象如果是指针类型降低实用性特化一些常见问题1.调用的模版为最匹配的有匹配的全特化优先走全特化模版2.特化时要注意参数匹配const指向要相同3.特化参数顺序必须匹配否则无法匹配对应模版templateclassTvoidfunc(constTt1){}templatevoidfuncDate*(constDate*t1){}//这里是错误的看起来TDate*和原来函数模版一样但是const指向对象是不同的原const指向T表示T是只读的同理const应该指向Date*而错误语句const是指向Date*指向内容的这里const指发生错误templatevoidfuncDate*(constDate*constt1){}//这样才符合const指向模版的分离编译一般情况下在编写程序时会对定义和声明进行分离在.h文件中声明在.cpp文件中定义但对于模版编程直接这样编写会报错一般函数在实现已经在.cpp文件中在链接后可找到对应实现但是对于模版函数由于被调用是在main函数所在文件中编译时找不到对应的定义只会记录对应函数名而模版定义的.cpp文件中没有调用并不会实例化导致在链接时无法找到对应函数的实现因此模版的声明和定义一般全部放在.h文件中
C++学习:模版
发布时间:2026/7/6 8:08:34
模版编程模版模版函数模版类模版的按需实例化模版的非类型模版参数模版的特化模版的分离编译模版泛型编程的基础编写与数据类型无关的调用代码实现代码复用//关键字templateclassT1,classT2,classT3...templatetypenameT1,typenameT2,typenameT3...模版函数会根据参数类型自动推导出对应函数实例templateclassT1,classT2TAdd(T1a,T2,b)//调用时会根据传参自动推导T的类型{returnab;}但当只有一个模版参数传入参数类型却不同则无法推导出对应类型若想继续使用该模版函数1.对数据进行显示实例化 2.显示实例化int a1;double b2.0;//显示实例化Addint(a,b);Adddouble(a,b);还有一种情况是必须要显示实例化的是当模版参数没有作为函数参数传入时templateclassTT*func(int n)//编译器此时无法推导T的类型{returnnewT[n];}//调用时必须显示实例化funcint(n);模版类模版类都需要显示实例化templateclassTclassA{private:T_a;};//显示实例化Ainta(5);在模版类的使用中往往需要 类名 T 的形式来标识模版类//类外定义成员函数templateclassTvoidStackT::Push(constTn){}//在类外使用模版参数需要先声明模版//模版类作为参数时需要templateTvoidLinkedListT::Push(ListNodeTnode){}注友缘类也需要以 类名 T 形式标识否则被认为是两个不同的类另外在未实例化模版类中通过 类名 T :: 取东西时编译器会无法区分是静态成员在未实例化时静态成员也可以取地址引用等操作还是内部类//typename可以告诉编译器这是一个类型typename vectorT::const_iterator itv.begin();模版的按需实例化在未调用时模版都不会被实例化有些语法错误也不会被编译器检查到例如对const对象进行修改模版的非类型模版参数类型模版参数class T或typename T非类型模版参数一个常量充当模版参数可不带参可带缺省值可做直接参数templatesize_tN10//可带缺省值voidPrint(){coutN;}Print();//可不带参Print5();//带参则覆盖原值模版的特化定义一个适用于特定类型的模版全特化templateclassTvoidPrint(Tt){}template//全特化voidPrint(intt){}半特化/偏特化templateclassT1,classT2voidPrint(T1t1,T2t2){}templateclassT1//偏特化voidPrint(T1t1,intt2){}templateclassT1,classT2//偏特化传入类型为指针voidPrint(T1*t1,T2t2){}//指针和引用可混用//指针偏特化是为了使模版T可以声明其它对象如果是指针类型降低实用性特化一些常见问题1.调用的模版为最匹配的有匹配的全特化优先走全特化模版2.特化时要注意参数匹配const指向要相同3.特化参数顺序必须匹配否则无法匹配对应模版templateclassTvoidfunc(constTt1){}templatevoidfuncDate*(constDate*t1){}//这里是错误的看起来TDate*和原来函数模版一样但是const指向对象是不同的原const指向T表示T是只读的同理const应该指向Date*而错误语句const是指向Date*指向内容的这里const指发生错误templatevoidfuncDate*(constDate*constt1){}//这样才符合const指向模版的分离编译一般情况下在编写程序时会对定义和声明进行分离在.h文件中声明在.cpp文件中定义但对于模版编程直接这样编写会报错一般函数在实现已经在.cpp文件中在链接后可找到对应实现但是对于模版函数由于被调用是在main函数所在文件中编译时找不到对应的定义只会记录对应函数名而模版定义的.cpp文件中没有调用并不会实例化导致在链接时无法找到对应函数的实现因此模版的声明和定义一般全部放在.h文件中