• C++进阶--模板及关键字typename


    //############################################################################
    /*
     *  模板介绍
     */
    //函数模板
    template<typename T>
    T square(T x) {
       return x*x;
    }
    
    //类模板
    template<typename T>
    class BoVector {
       T arr[1000];
       int size;
    public:
       BoVector():size(0) {}
       void push(T x) { arr[size] = x; size++; }
       T get(int i) const { return arr[i]; }
       int getSize() const { return size; }
       //void print() const {for(int i=0; i<size; i++) {cout << arr[i] << endl;}}
       void print() const { 
          const int* p = arr; 
          for(int i=0;  i<size; i++) {cout << *(p++) << endl;}
       }
    };
    
    template<typename T>
    BoVector<T> operator*(const BoVector<T>& rhs1, BoVector<T>& rhs2) {
       BoVector<T> ret;
       for (int i=0; i<rhs1.getSize(); i++) {
          ret.push(rhs1.get(i)*rhs2.get(i));
       }
       return ret;
    }
    
    int main()
    {
       cout << square(5) << endl;
    
       BoVector<int> bv;
       bv.push(2);
       bv.push(5);
       bv.push(8);
       bv.push(9);
       bv.print();
    
       cout << "Print squared bv: " << endl;
       bv = square(bv);
       bv.print();
    }
    
    
    //############################################################################
    /*
     *  函数模板类型省略
     */
    
    template<class T>
    void f() {
       ...
    }
    
    int main() {
       f<int>();  // T显式指定
    }
    
    
    // 类型T可以省略
    template<class T>
    void f(T t) {
       ...
    }
    
    int main() {
       f(67);  // 编译将其绑定为int型
    
       f<long>(67);  // 显示告诉编译器为long类型
    
       f(67L);
    }
    
    
    
    //############################################################################
    /*
     * 关键字typename及其用法
     */
    
    template<class T>
    void printAge(T& item) {
       ...
    }
    
    template<typename T>
    void printAge(T& item) {
       ...
    }
    
    //用于模板参数两者等效
    //使用typename更易理解
    //
    
    
    
    /*
     * Dependent Type 取决于模板参数的类型
     */
    template<typename T> A {
       vector<T> vec;
    }
    
    /*
     * Nested Dependent Type  包含在某个类里的dependent type
     */
    template<typename T> A {
       T::age myAge = 9;
       vector<T>::iterator itr;
    }
    
    
    
    /*
     * typename 用法二
     */
    class Dog {
       public:
       typedef int age;
    };
    
    template<class T>
    void printMyAge(T& item) {
       int n = 9;
       T::age* a = &n;
       cout << (*a) << endl;
    }
    
    int main() {
       Dog d;
       printMyAge<Dog>(d);    
    }
    
    
    // 上面的代码编译不过,T::age是类型,编译器当成变量
    
    //class Wolf {
    //   public:
    //   int age;
    //}; 
    
    
    /*
     * 法则: 当使用嵌套依赖类型的时候总是在前面加上typename,告诉编译器这是类型
     */
    
    
    
    // 例外: 在基类列表或者初始化列表中
    
    template<typename T>
    class D : public T::NestedBaseClass {
    public:
       D(int x) : T::NestedBaseClass(x) { 
          typename T::NestedBaseClass y;
          ...
       }
    }
    
    
    //############################################################################
    /*
     *  模板特化和偏特化
     */
    // std是一个特殊的命名空间,我们不能更改它的内容,但是可以为我们的类型提供特化的版本
    
  • 相关阅读:
    docker 部署springcloud项目【限制容器内存、CPU】
    docker容器中安装vim 、telnet、ifconfig、ping、curl命令
    开源仓库Harbor搭建及配置过程
    动手学深度学习 | PyTorch神经网络基础 | 14
    动手学深度学习 | 实战:Kaggle房价预测+课程竞赛:加州2020年房价预测 | 13
    动手学深度学习 | 数值稳定性+模型初始化和激活函数 | 12
    动手学深度学习 | 丢弃法 | 11
    动手学深度学习 | 模型选择+过拟合和欠拟合 | 09
    动手学深度学习 | 多层感知机+代码实现 | 08
    动手学深度学习 | Softmax回归+损失函数+图片分类数据集 | 07
  • 原文地址:https://www.cnblogs.com/logchen/p/10182696.html
Copyright © 2020-2023  润新知