C++: 模板初阶

目录

一、函数模板

1.概念

2.格式

3.原理

4.实例化

5.模板参数的匹配原则

二、类模板


一、函数模板

1.概念

函数模板是一个函数家族,和参数的类型无关。和逻辑有关。如果不同的两个(或者多个)函数只是参数不一样,逻辑完全一致,那么可以写一个函数模板。在调用时,就不需要写多个函数重载。

2.格式

template < typename1 T1, typename2 T2, typename3 T3,...,typenameN Tn>

//写个swap交换
template <typename T>
void swap(T&a , T&b>
{
   T tmp = a;
   a = b;
   b = tmp;
}

T也可以写成其他字母,我用T表示类型名字,只是它可以作为type的简写,容易读。

typename 是用于定义模板参数的关键字,可以用class代替,但是不能用struct代替。

3.原理

函数模板只是一个模具,它只有在调用的时候,才会实例化。

当给函数传参的时候,传的参数不一样,编译器会根据参数进行推演函数的参数类型应该是什么样,然后编译器自己写一份这样的函数给用户调用,所以并不是没有这份代码了,它就不存在了。只是把写重复的函数的代码的工作交给了编译器处理而已。

在汇编的时候,或者把函数的地址打印出来,可以看到不同参数调用同一份模板会产生不同的地址的。

4.实例化

使用函数模板调用函数的方式叫实例化。模板参数实例化分为隐式实例化和显式实例化两种。

隐式实例化:

编译器根据传的参数类型来推演将要实例化的实际参数类型。

传int 推int

传double 推double

template <typename T>
void swap(T& a, T& b)
{
    T tmp = a;
    a = b;
    b = tmp;
}

int main()
{
   int m=1, n=2;
   double p=1.00, q=2.00;
   
  //隐式实例化
   swap(m,n);
   swap(p,q);
   return 0;
}

显式实例化

显式实例化就是在调用的时候直接告诉编译器你的类型是啥。

template <typename T>
void swap(T& a, T& b)
{
    T tmp = a;
    a = b;
    b = tmp;
}

int main()
{
   
   int m = 1,n = 2;
//显式实例化
   swap<int>(m,n);
   return 0;
}

如果显式实例化类型不匹配,编译器会尝试使用隐式实例化,如果转换失败,那么编译器会报错。

5.模板参数的匹配原则

a.模板函数和非模板同名函数可以同时存在,并且模板函数也可以被实例化成非模板函数

b.在其他条件都相同的情况,编译器优先调用非模板函数。不会自己再写一个多余的。

c.如果类型不匹配,非模板函数可以自动类型转换,但是模板函数不会进行自动类型转换。这种情况,如果模板函数和调用时更匹配,编译器会用模板函数实例化,而不会用非模板函数的类型转换。

二、类模板

template <class T>
class Vector
{
  public:
  Vector(int capacity = 10)
  :_a = new T(capacity)
  ,_capacity(capacity)
  ,_size(0)
{}

  ~Vector();

  T& operator[](size_t pos)
 {
    assert(pos < size);
    return _a[pos];
 }
//...
  private:
  T* _a;
  int _capacity;
  int _size;
}

template <class T>
Vector<T>::~Vector()//类的析构模板放在类外写,要加类名
{
    if(_a)
    delete[](_a);
    _size=_capacity=0;
}

类模板实例化需要在类名后面加模板参数的类型。类名是类名。

Vector 是类名

Vector<int> 、Vector<T>才是类模板实例化。

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值