• 模板初步——定义模板


    一、关键点

    定义函数模板&类模板

    模板参数列表:非类型参数

    类模板类名的使用:依据作用域是否加上模板类型

    类模板和友元:设置友好关系

    模板参数:使用类的类型成员、默认模板实参

    成员模板的使用:非模板类的成员模板、模板类的成员模板

    二、定义函数模板

    //模板参数T是一个类型 
    template <typename T>
    bool cmp(const T &a, const T &b)
    {
    	return a < b;
    } 
    //模板参数N是一个非类型参数 
    template <unsigned N>
    void get_val(int (&arr)[N])
    {
    	for (const auto &v : arr)
    		cout << v << " ";
    }
    

    注:一个非类型参数可以一个整型,或者是一个指向对象或函数类型的指针或(左值)引用。

    注:绑定到非类型整型参数的实参必须是一个常量表达式(从而允许编译器在编译时实例化模板)。

    三、定义类模板

    template <typename T>
    class Blob
    {
    public:
    	using size_type = typename vector<T>::size_type;
    	//...
    } 
    
    int main()
    {	
    	Blob<int> b;
        return 0;
    }
    

      

    四、类模板的成员函数

    template <typename T>
    class Blob
    {
    public:
    	using size_type = typename vector<T>::size_type;
    	//...
    private:
    	void check(size_type i, const string &s) const;
    };
    //成员函数类外定义
    template <typename T>
    void Blob<T>::check(size_type i, const string &msg) const
    {
    	//...
    }
    

    注:定义在类模板内的成员函数被隐式声明为内联函数。

    注:一个类模板的成员函数只有在使用时才被实例化。

    五、类模板的友元

    友元是模板:类可以授权给所有友元模板实例,也可以只授权给特定实例

    友元不是模板:友元被授权可以访问所有模板实例

    1. 一对一友好关系(友元是模板,且友元的模板类型与类模板的一致)

    //Blob的友元是模板函数operator==和模板类BlobPtr 
    template <typename> class Blob;	//该声明是operator==函数的参数声明所需要的 
    template <typename T> bool operator==(const Blob<T>&, const Blob<T>&);
    template <typename> class BlobPtr;	//该声明是Blob中的友元声明所需要的 
    
    template <typename T>
    class Blob
    {
    	//每个Blob实例将访问权限授予用相同类型实例化的BlobPtr和相等运算符 
    	friend class BlobPtr<T>;
    	friend bool operator==(const Blob<T>&, const Blob<T>&);
    	//...
    };
    
    template <typename T> class pal;
    template <typename T> class C { //C的每个实例将相同实例化的pal声明为友元 friend class pal<T>; }
    template <typename T> class pal;
    
    class C {
    	//用类C实例化的pal是C的一个友元 
    	friend class pal<C>;
    }

    2. 通用和特定的模板友好关系

    template <typename T> 
    class C {
    	//pal的所有实例都是C的每个实例的友元 
    	template <typename X> friend class pal;
    }
    class C {
    	//pal的所有实例都是C的友元 
    	template <typename X> friend class pal;
    }
    
    template <typename T> 
    class C {
    	//pal是C所有实例的友元 
    	friend class pal;   //非模板类
    }
    

    注:可以将模板类型参数声明为友元

    六、模板参数

    1. 使用类的类型成员

    T::value_type * p;
    

    上面这句代码的默认含义是T类型的名为value_type的static数据成员与名为p的变量相乘。

    为了显式声明value_type是一个模板类型参数的类型成员,我们可以如下定义:

    typename T::value_type * p;
    

    2. 默认模板实参

    与函数默认实参一样,对于一个模板参数,只有当它右侧的所有参数都有默认实参时,它才可以有默认实参。

    如果一个类模板为其所有模板参数都提供了默认实参,且我们希望使用这些默认实参,那就要:

    template <class T = int> 
    class C {
    	//...
    }; 
    C<> c1;		//空<>表示我们希望使用默认实参 
    C<double> c2;
    

     

    七、成员模板

    成员模板:本身是模板的成员函数,它不能是虚函数

    1. 模板类的成员模板

    template <typename T> 
    class Blob {
    	template <typename It> 		//此构造函数有自己的模板类型参数It 
    	Blob(It b, It e);
    	//...
    }
    
    template <typename T>
    template <typename It>
    Blob<T>::Blob(It b, It e) :data(make_shared<vector<T>>(b, e))
    {
    }
    

    2. 非模板类的成员模板

    与正常的函数模板没有区别,只不过作用域是在类内

  • 相关阅读:
    Druid时序数据库常见问题及处理方式
    常用环境变量配置
    Hadoop学习(四) FileSystem Shell命令详解
    Hadoop学习(二) Hadoop配置文件参数详解
    Hadoop学习(一) Hadoop是什么
    Sqoop帮助文档
    CentOS搭建Sqoop环境
    Zookeeper系列(二) Zookeeper配置说明
    查看sql 作业明细及运行记录
    java性能测试工具 jprofiler
  • 原文地址:https://www.cnblogs.com/xzxl/p/7856307.html
Copyright © 2020-2023  润新知