zoukankan      html  css  js  c++  java
  • c++模板类

    嵌套模版

    template<typename T>
    class out
    {
    private:
        class inter
        {
        private:
            T value;
        public:
            inter();
        };
    };
    template<typename T>
    out<T>::inter::inter()
    {}
    
    template <typename T>
    class out
    {
    private:
        template <typename C>
        class inter
        {
            C value;
        public:
            inter();
        };
    };
    template <typename T>
        template <typename C>
        out<T>::inter<C>::inter()
        {}
    

    将模版作为参数

    template < template<typename T>class Thing >
    class crab
    {};
    template <typename T>
    class King
    {}
    

      上面template<typename T>clas是类型,Thing是指这种类型的别名,King就是这种类型。

    模版与友元函数

    在模板类中声明友元函数,分四种类型。

    1. 不需要模板参数的非模板函数。
    2. 需要模板参数的非模板函数。
    3. 需要模板参数的模板函数,使用类模板参数特化。
    4. 需要模板参数的模板函数,自带模板参数。
    5. 需要模板参数的模板函数,自带多个模板参数。
    template <typename V>
    class A;
    template <typename V>
    void f3(A<V>& a);
    
    template <typename T>
    class A
    {
    public:
    	friend void f1();	
    	friend void f2(A<T>& a);
    	friend void f3<T>(A<T>& a);
    	template <typename U>
    	friend void f4(A<U>& a);
        template<typename C,typename D>
        friend void f5(C &a,D &b);
    };
    

    非模板的友元函数

    不需要模板参数

      上面的f1是A<int>,A<double>等的友元函数,也就是无论多少种实例,都只有一个函数。它可以访问①全局对象,②通过全局指针访问非全局对象,③访问类的静态函数。

    #include <iostream>
    using namespace std;
    template <typename T>
    class A
    {
    private:
        static int num;
    public:
        A(){++num;}
        ~A(){--num;}
        friend void f1();
    };
    template<typename T>
    int A<T>::num = 0;
    void f1()
    {
        cout << A<int>::num << "	" << A<double>::num << endl;
    }
    int main()
    {
        A<int> a,b,c;
        A<double> d,e;
        f1();
        return 0;
    }
    

    需要模板参数

      f2(A<int> &)A<int>的友元函数,但不是A<double>的友元函数,也就是说每种类型的实例都会有一个f2之对应。但是如果想在类外为f2友元函数写定义,只能直接为每一种特化后的参数写一个。在类内写定义会随着类的实例化自动生成对应的函数。

    #include <iostream>
    using namespace std;
    template <typename T>
    class A
    {
    private:
        static int num;
        T value;
    public:
        A(const T &n):value(n){++num;}
        ~A(){--num;}
        friend void f2(A<T> &a);//类外定义,需要每种类型都定义
        friend void f2_2(A<T> &a)//类内定义,自动生成函数
        {
            cout << "f2_2: " << a.value << endl;
        }
    };
    template<typename T>
    int A<T>::num = 0;
    void f2(A<int> &a)
    {
        cout << "f2: " << a.value << endl;
        //cout << A<double>::num  << endl;,说明f2(A<int> &a)无法访问A<double>的数据
    }
    int main()
    {
        A<int> a(9);
        A<double> d(9.9);
        f2(a);
        //f2(d);//undefined reference to `f2(A<double>&)'
        f2_2(a);
        f2_2(d);
        return 0;
    }
    

    模版的友元函数

    使用类模板参数特化

    #include <iostream>
    using namespace std;
    template <typename V>
    class A;
    //在类的前面声明模板函数
    template <typename V>
    void f3(A<V>& a);
    template <typename T>
    class A
    {
    private:
        static int num;
        T value;
    public:
        A(const T &n):value(n){++num;}
        ~A(){--num;}
        friend void f3<T>(A<T>& a);//可以写为friend void f3<>(A<T> &a),编译器会自动推导那个T
    };
    template<typename T>
    int A<T>::num = 0;
    template <typename T>
    void f3(A<T> &a)
    {
        cout << "f3: " << a.value << endl;
    }
    int main()
    {
        A<int> a(9);
        A<double> d(9.9);
        f3(a);
        f3(d);
        return 0;
    }
    

      f3(A<int>)A<int>的友元,但不是A<double>的友元,也就是说每种类型的实例都会有一个f3之对应。
      与f2的区别。

    • f2不需要模板参数推导,相比f3是更优的匹配,两者同名时会优先调用f2。
    • f3在类外定义时无需像f2那样,一个个定义。

    自带模板参数

    自带单个模板参数

    #include <iostream>
    using namespace std;
    template <typename V>
    class A;
    template <typename V>
    void f3(A<V>& a);
    
    template <typename T>
    class A
    {
    private:
        T value;
        static int num;
    public:
        A(const T &n):value(n){++num;}
        ~A(){--num;}
    	friend void f3<T>(A<T>& a);
    	template <typename U>
    	friend void f4(A<U>& a);
    };
    template<typename T>
    int A<T>::num = 0;
    
    template <typename T>
    void f3(A<T> &a)
    {
        cout << "f3: " << a.value << endl;
    }
    
    template <typename U>
    void f4(A<U> &a)
    {
        cout << "f4: " << a.value << endl;
    }
    
    int main()
    {
        A<int> a(9);
        A<double> d(9.9);
        f3(a);
        f4(a);
    	return 0;
    }
    

      这样开起来f3和f4是没有区别的。由于f4中的函数模板参数不一定是跟类的模板参数一样,所以f4(A<int>)f4(A<double>)可以是A<int>的友元,也可以是A<double>的友元。下面例子可以说明。

    #include <iostream>
    using namespace std;
    template <typename V>
    class A;
    template <typename V>
    void f3(A<V>& a);
    
    template <typename T>
    class A
    {
    private:
        T value;
        static int num;
    public:
        A(const T &n):value(n){++num;}
        ~A(){--num;}
    	friend void f3<T>(A<T>& a);
    	template <typename U>
    	friend void f4(A<U>& a);
    };
    template<typename T>
    int A<T>::num = 0;
    
    template <typename T>
    void f3(A<T> &a)
    {
        cout << "f3: " << A<double>::num << endl;
    }
    
    template <typename U>
    void f4(A<U> &a)
    {
        cout << "f4: " << A<double>::num << endl;
    }
    
    int main()
    {
        A<int> a(9);
        A<double> d(9.9),e(1.9);
        f3(a);//调用出现错误
        f4(a);
    	return 0;
    }
    

    自带多个模板参数

    #include <iostream>
    using namespace std;
    template <typename T>
    class A
    {
    private:
        T value;
    public:
        A(const T &n):value(n){}
        ~A(){}
        template <typename C,typename D>
        friend void f5(A<C> &c,A<D> &d);
    };
    template <typename C,typename D>
    void f5(A<C> &c,A<D> &d)
    {
        cout << c.value << '	' << d.value << endl;
    }
    int main()
    {
        A<int> a(9);
        A<double> d(9.9);
        f5(a,d);
    	return 0;
    }
    

    模版别名

    typedef array<int,13> myarray;
    using myarray = array<int,13>;
    template <typename T>
    using myarray = array<T,13>;
    
  • 相关阅读:
    WebService 通过POST方式访问时候,因 URL 意外地以“/方法名”结束,请求格式无法识别 解决办法
    SQL Server 触发器
    JS数据类型转换
    .net注册到IIS
    SQL Server 常用sql操作语句
    浅解DLL
    有关注册表API函数
    [原]惜 时
    图解双机共享ADSL上网
    如何在C#中使用全局鼠标、键盘Hook
  • 原文地址:https://www.cnblogs.com/h-hg/p/8783935.html
Copyright © 2011-2022 走看看