STL学习过程中的笔记

    技术2025-07-17  11

    梳理STL学习过程中的笔记

    学STL,首先要搞清楚什么是模板

    函数模板

    或者是用 <Class T>都是一样的

    template <typename T>2   3  int function(const T& a, const T& b)4   5  {6   7      ... ...8   9  }10   11  template <typename T>12   13  inline int function(const T& a)14   15  {16   17      ... ...18   19  }

    怎么使用呢?

    直接填值就可以了

    编译器根据值的类型进行判断,不用多操心

    函数模板的实例化

    function(1, 2);2   3  CString str1, str2;4   5  function(str1, str2);

    推断类型的时候不带强制类型转换的 否则怎么推断呢

    在模板函数内部, 是可以强制类型转换的

    比如模板函数调用某个库函数的时候,传给库函数的类型不完全吻合时

    PS:

    VC++中有<string.h>文件,它就是C中的那个; 而<cstring>文件实际上只是在一个命名空间std中include了<string.h>,这是因为C++要减少名称污染;

    类模板

    和函数模板完全一样 只是实例化的时候方式不同

    实例化的时候 会被强制类型转换的

    template <typename T>2   3  class Stack4   5  {6   7      push(T& a);8   9      ... ...10   11  }

    类的实例化

    Queue<int> qs;

    形成一个int代替形参表的类类型

    并产生该类型的一个对象 qs

    ====================================================================

    外界定义的和形参一样的 会在模板内部屏蔽掉

    typedef double T2   3  template <typename T>4   5  int function(T& a )6   7  {8   9      外界定义的T会被隐藏掉10   11  }

    内部不允许再次使用形参做变量名

    template <typename T>2   3  int function(T& a )4   5  {6   7      typedef double T; // 非法8   9  }

    形参中每一种类型前面都要加typename或者class

    类型的子类型

    T是一个类型 SubT是T类型的子类型

    什么是子类型?

    就是比如T是一个类

    template <class T>2   3  class Cls4   5  {6   7      typedef int SubT;8   9  } 在定义的时候 1  template <typename T>2   3  T fun(T& a)4   5  {6   7       T::SubT* p;  // 系统不知道SubT是子类型  会以为是T的静态成员变量 认为是两者的乘积(T::SubT)*(p)8   9  } 所以要声明 1  template <typename T>2   3  T fun(T& a)4   5  {6   7      typename T::SubT* p;  // SubT是一种类型8   9  } 当然SubT也可以被另一种形参所笼罩 1  template <class T,class U>2   3  class Cls4   5  {6   7      typedef U SubT;8   9  } 很无语吧!

    ==========================================================

    现在看看非类型模板形参是怎么回事儿

    #include <iostream> using namespace std;   template <class T,int N>int getDim(const T (&a)[N]) {         return N;}   7   8  int main() {     10      double d[234];     11      cout << getDim(d);     12      return 0; 13  } 14   15   

    由于有这样的定义

    const T (&a)[N]

    所以实例化的时候 &a 实例化为d     N实例化为234

    相当于形参表为 <double, 234>

    只是传递的时候只需要传递 d 就可以了

    为什么只需要传递d呢 因为d是函数getDim的参数  类型和个数都由d自己的属性来确定

    数组d的类型被自动识别 把T实例化为double类型

    类型为int的N被自动识别 实例化为数组d的单元数

    类的等价性???

    ==============================================================================

    数组的引用传递

    void print(int (&arr)[10]);    // 需要指定数组长度,长度不一致将不匹配int main(){    int i[2];    int k[10];    print(i);// error    print(k);//OK}

    所以在模板中认为数组引用传递的时候  如果两个数组的长度不同 他们是不同的类型

    template <typename T>T fref(T &, T&){    ... ...}int a[5];int b[10];fref(a, b);// error类型不同

    更复杂一点的实例化应用是  用函数指针指向某个实例化的模板  这样模板就实例化为那个指针的类型

    template <typename T>int compare(const T&, const T&);3   4  int (*pf)(const int&, const int&) = compare;  
    最新回复(0)