zoukankan      html  css  js  c++  java
  • 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是一个特殊的命名空间,我们不能更改它的内容,但是可以为我们的类型提供特化的版本
    
  • 相关阅读:
    人这一辈子
    理性不是逆来顺受
    旧瓶新酒:江城子
    HVAC专业相关网站
    韩寒:主子,奴才和狗
    百无一用是书生
    inove主题文章字体修改
    这个世界清净了:再见人人
    ActiveX控件开发(转)
    GIS大讲堂内所有讲座的索引(更新至2008年6月26日)(转)
  • 原文地址:https://www.cnblogs.com/logchen/p/10182696.html
Copyright © 2011-2022 走看看