• 【C++】模版-初阶


    目录

    泛型编程--模版

    函数模版

    类模版


    泛型编程--模版

    函数模版

    1. 如何实现一个通用的交换函数呢?
    2.  void Swap(int& left, int& right)
    3.  {
    4.      int temp = left;
    5.      left = right;
    6.      right = temp;
    7.  }
    8.  void Swap(double& left, double& right)
    9.  {
    10.      double temp = left;
    11.      left = right;
    12.      right = temp;
    13.  }
    14.  void Swap(char& left, char& right)
    15.  {
    16.      char temp = left;
    17.      left = right;
    18.      right = temp;
    19.  }
    20.  ......

    使用函数重载虽然可以实现,但是有一下几个不好的地方:

    1. 重载的函数仅仅是类型不同,代码复用率比较低,只要有新类型出现时,就需要用户自己增加对应的函 数

    2. 代码的可维护性比较低,一个出错可能所有的重载均出错 那能否告诉编译器一个模子,让编译器根据不同的类型利用该模子来生成代码呢?

    函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本。

    函数模板格式:

    template

    用class也一样:

    template

    1.  template <class T>
    2.  void Swap(T &x, T &y)
    3.  {
    4.      T tmp = x;
    5.      x = y;
    6.      y = tmp;
    7.  }
    8.  ​
    9.  int main()
    10.  {
    11.      int a=1,b=2;
    12.      Swap(a,b);
    13.      cout<" "<
    14.  ​
    15.      double aa=1.1,bb=2.1;
    16.      Swap(aa,bb);
    17.      cout<" "<
    18.  ​
    19.  ​
    20.      return 0;
    21.  }

    当然 虽然提供了模版,但在使用时,int型与double型调用的函数都是不同的

    函数模板的原理:

    函数模板是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具。所以其实模板就是将本来应该我们做的重复的事情交给了编译器

    类型推演(实例化)

    若在使用模版的同时,自己写出了有具体类型的相关函数,编译器会优先调用自己实现的函数:

    1.  template <class T>
    2.  void Swap(T &x, T &y)
    3.  {
    4.      T tmp = x;
    5.      x = y;
    6.      y = tmp;
    7.  }
    8.  ​
    9.  void Swap(double &x, double &y)
    10.  {
    11.      double tmp = x;
    12.      x = y;
    13.      y = tmp;
    14.  }

    函数模板的实例化:

    用不同类型的参数使用函数模板时,称为函数模板的实例化。模板参数实例化分为:隐式实例化和显式实例化。

    1.隐式实例化:让编译器根据实参推演模板参数的实际类型:

    1.  template <class T>
    2.  T Add(const T &left, const T &right)
    3.  {
    4.      return left + right;
    5.  }
    6.  int main()
    7.  {
    8.      int a1 = 10, a2 = 20;
    9.      double d1 = 10.0, d2 = 20.0;
    10.      Add(a1, a2);
    11.      Add(d1, d2);
    12.      /*
    13.      该语句不能通过编译,因为在编译期间,当编译器看到该实例化时,需要推演其实参类型 通过实参a1将T推演为int,通过实参d1将T推演为double类型,但模板参数列表中只有一个T, 编译器无法确定此处到底该将T确定为int 或者 double类型而报错
    14.        注意:在模板中,编译器一般不会进行类型转换操作,因为一旦转化出问题,编译器就需要背黑锅
    15.           Add(a1, d1);
    16.          */
    17.      // 此时有两种处理方式:1. 用户自己来强制转化 2. 使用显式实例化
    18.      Add(a, (int)d);
    19.      return 0;
    20.  }

    2.显式实例化:在函数名后的<>中指定模板参数的实际类型

    1.  template <class Z>
    2.  Z Add(const Z &left, const Z &right)
    3.  {
    4.      return left + right;
    5.  }
    6.  ​
    7.  int main()
    8.  {
    9.      int a1 = 10, a2 = 20;
    10.      double d1 = 10.1, d2 = 22.2;
    11.      cout << Add(a1, a2) << endl;
    12.      cout << Add<int>(a1, d2) << endl;
    13.      cout << Add<double>(d1, a2) << endl;
    14.      cout << Add(d1, d2) << endl;
    15.  ​
    16.      return 0;
    17.  }

    如果类型不匹配,编译器会尝试进行隐式类型转换,如果无法转换成功编译器将会报错。

    类模版

    类模板的定义格式:

    1.  template<class T1, class T2, ..., class Tn>
    2.  class 类模板名
    3.  {
    4.   // 类内成员定义
    5.  };
    6.  template <class T>
    7.  class Stack
    8.  {
    9.  private:
    10.      T *_a;
    11.      size_t _top;
    12.      size_t _capaicty;
    13.  ​
    14.  public:
    15.      Stack(int capaicty = 4)
    16.     {
    17.          _a = new T[capaicty];
    18.          _top = 0;
    19.          _capaicty = capaicty;
    20.     }
    21.      ~Stack()
    22.     {
    23.          delete[] _a;
    24.          _capaicty = _top = 0;
    25.     }
    26.  };
    27.  ​
    28.  int main()
    29.  {
    30.      //类只能 显示实例化
    31.      Stack <int>st1;
    32.      Stack <double>st2;
    33.  ​
    34.      return 0;
    35.  }

  • 相关阅读:
    R语言将数据转化为DALEX包期望的格式、使用DALEX包的explain函数对多个h2o算法模型构建解释器进行解释分析、使用验证集数据构建模型解释器
    力扣刷题学习SQL篇——1-3 选择(从不订购的客户——使用not in)
    Java配置线程池
    Day 36 贪心算法 part05 : 435. 无重叠区间 763.划分字母区间 56. 合并区间
    Java宝典-抽象类和接口
    https部署(nginx代理) keycloak ,js加载不出来的问题
    视频加密的误解
    我们来聊聊锁升级吧
    【MySql】MySQL概述及其语法概述
    关于KMP模式匹配的一些思考
  • 原文地址:https://blog.csdn.net/2301_77649794/article/details/134471845