C++函数模板和类模板

目录

一、模板

  1.1 模板的定义

  1.2 泛型模板

  1.3 模板的特点

二、函数模板

  2.1 函数模板基本格式            

  2.2 函数模板调用

  2.3 函数模板和普通函数的区别

  2.4 函数模板重载

  2.5 函数模板特化

  2.6 多文件实现函数模板

  2.7  函数模板的嵌套

  2.8 函数模板的非类型参数

三、类模板

  3.1 类模板格式

  3.2 类模板和函数模板区别


一、模板

  1.1 模板的定义

        模板是一种参数化多态性的工具,可以为逻辑功能相同而类型不同的程序提供代码共享的机制。分为函数模板和类模板。

  1.2 泛型模板

        用一个标志来表示类型,不是实际的类型。独立于任何特定类型的编程,c++的一个部分。

  1.3 模板的特点

        1.可用来创建动态增长和减小的数据结构。

        2.它是类型无关的,因此具有很高的可复用性。

        3.它在编译时而不是运行时检查数据类型,保证了类型安全。

        4.它是平台无关的,可移植性。

        5.可用于基本数据类型。

二、函数模板

  2.1 函数模板基本格式            

template<class T1,class T2> //或者是 template<typename T>
返回值 函数名(参数)
{

}

        template:声明创建模板。

        <>:用尖括号,里面可以一个或者多个通用类型。

        class:(也可以用typename)表明后面的T1是一个通用类型,或者叫虚拟类型。

        T1/T2:通用类型或者虚拟类型,(理解成类型)可以在函数中直接当做普通类型使用。

  2.2 函数模板调用

        1.函数名 <实际类型1,实际类型2>(参数列表);

          显式类型推导   fun<int>(1,2);

        2.函数名(参数);

           隐形类型推导   fun(1,2);

        3.注意:显示类型推导参数和推导的类型必须一致。

                      如果有普通函数和模板函数,在调用模板函数时可以用显示调用,省略类型的方式  

swap<>(1,2);

  2.3 函数模板和普通函数的区别

        1.普通函数只可以有一种数据类型相匹配。函数模板有多种类型。

        2.隐式推导优先使用普通函数,只有普通函数不匹配才使用函数模板。

        3.函数模板只有在调用时,才会构建函数,而普通函数是在编译时。

        4.普通函数调用时可以发生自动类型转换,而函数模板不行。

  2.4 函数模板重载

        和普通函数的重载相似。也是同一个作用域内函数名相同参数列表不同。

        1.参数顺序不同重载

template <class T1,class T2>void swap1(T2 a,T1 b)
template <class T1,class T2>void swap1(T1 a,T2 b)

        2.参数个数不同重载

template <class T>void swap1(T a)
template <class T1,class T2>void swap1(T1 a,T2 b)

        3.注意:在函数参数顺序不同的重载中,实例化的时候不可以是相同类型。

 swap1<int ,int >(1,2)

  2.5 函数模板特化

        1.定义:为了解决函数模板的局限性,在定义函数模板时候,直接确定好T的类型。也就是特定的类型模板。

        2.格式:

template<class T> 
返回值  函数名(类名& 对象)
{ 
}

        3.匹配:如果传入的是自定义类型,并且和特化版本匹配,会优先使用特化版本。

        4.注意:如果特化后,类型确定才可以使用自定义类型中的成员变量和方法。

  2.6 多文件实现函数模板

        在定义函数或者类的时候,会有.h文件和cpp文件,定义和申明是分开的。那么编译的时候就会出现连接错误的原因,这是因为函数模板是在调用时确定的,而调用时.h文件中没有函数实现,出现连接错误,找不到函数体。

        解决方法:

        1.在main中引用#include <xxx.h>  和 #include <xx.cpp>

        2.将模板的定义和申明都放在.h头文件中。

  2.7  函数模板的嵌套

        1.定义:在函数模板中调用另外一个函数模板。

        2.例如:

template<class T>
T max_2(T a,T b)
{
    retirn a>b?a:b;
}
template<class T>
T max_3(T a,T b, Tc)
{
    T temp=max_2(a,b);
    return temp>c?temp:c;
}

  2.8 函数模板的非类型参数

       1. 定义:如果我们在使用函数模板时想给函数模板传入一个特定的确定参数,但又不希望放在小括号中。可以通过非类型参数实现。在模板<>中加了一个参数,但这个参数不是类型参数,是具体的某一个值。

        2.格式:

template<class T,基本数据类型 变量名>
返回值 函数名(T& 变量)
{
}

        3.例如:

template <class T,int size>
void showArr(T* arr)
{
}

        在上述例子中,size是通过模板传入到函数中,可以当做普通变量使用。并且非类型参数都是常量,在函数中不允许修改,只可以使用,所以定义非类型参数变量时候,需要加const修饰。 

三、类模板

  3.1 类模板格式

        1.格式:

template<typename T>
class person 
{ 
    T age; 
};

        2.实例化:

        类名<类型> 变量名(参数);

person<int>zhangsn(18);

  3.2 类模板和函数模板区别

        1.函数模板可以使用隐式类型推导,但类模板不可以,必须显示推导。

        2.类模板在定义template时候,可以加上默认参数。例如:

template<class T1,class T2=string>

        3. 在模板中的默认参数类型中,如果所有模板参数都是缺省,但类模板进行实例化的时候,尖括号不可以省略。例如:

template<class T1=int,class T2=string>
class person
{    
    T1 age;
    T2 name;
};
int main()
{     
    person<> wang(3,"wang");
    return 0;
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值