C++模板的使用

发布于:2022-12-26 ⋅ 阅读:(461) ⋅ 点赞:(0)

什么是模板:

        这里只讲函数模板,模板的话就是泛型编程,泛型编程是用一个标志来表示类型,不是实际的类型。独立于任何特定类型的编辑,是C++的一部分,不是全部。

可能很多朋友不明白什么是模板,打个比方。模板就是一个模板一样的,做数学题不会做,有个公式,按照想法套进去就行了。还有PPT,我们使用或者要用PTT,有多少人是一顿骚操作。从零到有创建出来的。其实不然,我们只要一个空白的模板,然后把我们想要的内容制作出来就行了,模板就是最基础的东西。最简单的理解,它就是一个框架,需要填写内容。当然,小伙伴们也知道他的作用了,就是方便开发,写开发就不需要自己想模板了,直接照搬,还有一个作用就是提高复用率。以上就是一个简单叙述,那么接下来就是讲关于它的知识点了。

先给大家讲三个关键字。

         template-----声明创建模板

         typename--------表明后的类型是一个通用类型,也可以叫虚拟类型(可以用class代替)

         T1--------通用类型或者虚拟类型,也是一种类型,可以在函数中直接当做普通函数来使用。

 2.函数模板:
   格式:template<class T1,typename T2>
             返回值 函数名(参数){  }

 以上就是模板的一个使用。

 函数模板的调用:
 第一种:  函数名 <实际类型1,实际类型2>(参数列表);
                 显式类型推导   fun<int>(1,2);

  第二种: 函数名(参数);
                    隐形类型推导
    5.注意:显示类型推导 参数和推导的类型必须一致。
              如果有普通函数和模板函数,在调用时可以用显示调用,省略类型的方式  swap<>(1,2)
    
   6.普通函数和函数模板的区别:
    函数只可以有一种数据类型相匹配。模板有多种类型
    隐式推导优先使用普通函数,只有普通函数不匹配才使用函数模板
    函数模板只有在调用时,才会构建函数,而普通函数是在编译时。
    普通函数调用时候可以发生自动类型转换,而函数模板不行。  
    
   7.函数模板重载
    和普通函数的重载相似。也是同一个作用域类函数名相同参数列表不同。
     以下是参数顺序不同的重载
     template <class T1,class T2>void swap1(T2 a,T1 b)
      template <class T1,class T2>void swap1(T1 a,T2 b)
     注意,在函数参数顺序不同的重载中,实例化的时候不可以是相同类型
     例如  swap1<int ,int >(1,2)则没法匹配哪个函数。
     以下是参数个数不同的重载
         template <class T1,class T2>   void swap1(T1 a,T2 b)
         template <typename T2>  void swap1(T2 t)
         传入不同的参数,调用不同的版本
     
     
8.函数模板特化
   定义:为了解决函数模板的局限性,在定义函数模板时候,直接确定好T的类型。也就是特定的类型模板。
    格式: template<class T> 返回值  函数名(类名& 对象){ }
    匹配:如果传入的是自定义类型,并且和特化版本匹配,会优先使用特化版本
    注意:如果特化后,类型确定才可以使用自定义类型中的成员变量和方法。

9.多文件实现函数模板
     在定义函数或者类的时候,会.h和cpp文件,定义和申明分开。
     出现连接错误的原因:函数模板是在调用时确定的版本,而调用时.h中没有函数实现,出现连接错误,找不到函数体。
     如果分开后,编译会出现连接错误。
     第一种办法:在main中#include <xxx.h>  和 #include <xx.cpp>
     第二种办法:模板的定义和申明都放在.h头文件中。

 10. 函数模板的嵌套
     定义:在函数模板中调用另外一个函数模板
     
    
11.函数模板的非类型参数
     希望传入函数一个特定的确定参数,但不希望放在小括号中。
     可以通过非类型参数实现。在模板<>中加了一个参数,但这个参数不是类型参数,是具体的某一个值。
     格式:template<class T,基本数据类型 变量名>
               返回值 函数名(T& 变量)
      例如:template <class T,int size>
                 void showArr(T* arr);
      注意:在上例子中,size是通过模板传入到函数中,可以当做普通变量使用
                非类型参数都是常量,在函数中不允许修改,只可以使用,定义非类型参数变量时候,需要加const。   

  
     
12.类模板
     建立一个通用的类,如果希望成员变量的类型是任意的,用类模板实现。
     类模板不是一个实际的类型,是虚拟的,和ppt模板一样,实例化的时候才会构建类。
     格式:template<typename T>
               class test { T age; };
      实例化: 类名<类型> 变量名(参数);
     类模板和函数模板区别

 


     

函数模板可以使用隐式类型推导,但类模板不可以,必须显示推导
      类模板在定义template时候,可以加上默认参数。template<class T1,class T2=string>
      在模板中的默认参数类型中,如果所有模板参数都是缺省,但在类进行实例化的时候,尖括号不可以省略template<class T1=int,class T2=string>
class person{};     person<> wang(3,"wang");