• 模板的进阶 非类模板参数 类模板的特化


    模板的进阶
    非类模板参数
    类模板的特化
    静态数组:array:template < class T, size_t N > class array; array为可以存放N个元素的数组模拟实现:
    #include<iostream>
    using namespace std;
    namespace bit{
    template < class T, size_t N > ;
    class array{
        public:
        private:
            //T类型参数,N非类型参数
            T array[N];   
        };
    }
     
    int main(){
        bit::array<int,10> a;
        return 0;
    }
     
        模板---->任意类型都可以处理
        特化---->对模板不能处理或者处理有误的类型进行特殊化处理(比如对于char *类型,是一个字符串,比较时应该通过字符串的方法进行比较,但是通过这个模板进行比较时直接用大于小于><进行比较,所以需要对模板进行特化)
            1.必须提供一个类模板(对于函数模板,一般不进行特化)
            
    template<class T>
    T& Max(T& a,T& b){
        return a>b?a:b;
    }
    template<>
    char *& Max<char *>(char *& left,char *& right){
        //不能加const,否则会出错,报错:不是函数模板的专用化
        //加了之后对于特化的成本增加了
        //如果处理不了,直接给出这种处理的函数即可,不需要特化
        if(strcmp(left,right)>0){
            return left;
        }
        retrun right;
    }
     
    int main(){
        int a=0;
        int b=3;
        cout<<Max(a,b)<<endl;
        char *p1="hello";
        char *p2="world";
        cout<<Max(p1,p2)<<endl;
        return 0;
    }
     
    类模板的特化:
        1.全特化:类模板实例化期间将类型全给出来比如:class Data<int , double>
        2.偏特化(1)部分特化:class Data<int ,T>
                       (2)   让模板的参数列表中的类型参数限制更加严格class Data<T*,T*>
    应用场景:识别被拷贝的元素的类型是内置类型还是用户自定义类型?
                    内置类型:不会涉及资源的管理
                    自定义类型:会涉及类型的管理
        类型萃取:
            
    //实现通用的拷贝函数:
    template<>
                                                  
    //内置类型
    struct TypeTraits<char>{
        typedef TrueType POD_TYPE;
    };
     
    template<>
    struct TypeTraits<double>{
        typedef TrueType POD_TYPE;
    };
     
    struct TypeTraits<int>{
        typedef TrueType POD_TYPE;
    };
     
    template<>
    struct TypeTraits<float>{
        typedef TrueType POD_TYPE;
    };
                                                 
    //是实现的通用的类型,进而判断是内置类型还是自定义类型
                                                 
     
    template<>
    struct TypeTraits<T>{
        typedef FalseType POD_TYPE;
    };
                                               
     
    struct TrueType{
        static bool Get(){
            return true;
        }
    };//代表内置类型
     
    struct FalseType{
        static bool Get(){
            return false;
        }
    };//代表自定义类型
     
        
    template<class T>
    void Copy(T* dst,T* src,size_t size){
        if(TypeTraits<T>::POD_TYPE::Get()){
            memset(dst,src,sizeof(T)*size);
        }
        else{
            for(i=0;i<size;++i){
                dst[i]=src[i];
            }
    }

    模板的分离编译:
        预处理阶段---->编译---->汇编---->链接---->可执行程序
        1.预处理 宏替换,宏展开,删除注释,包含头文件
        2.编译:语法分析(语法树—>中序遍历),语义分析,词法分析(扫描),代码优化;编译器只编译当前工程的所有源文件,头文件不参与编译(?????),头文件已经展开了。对于当前工程的所有源文件,分别单独编译,分别生成目标文件
     
        1.对模板进行简单的语法检测
        2.生成代码-->前提(实例化)
            未解决的符号表
                编译期间生成未解决的符号表,链接期间进行解决(链接期间到别的已解决的符号表中去找,如果没找到则报错:无法解析的外部符号;如果找到了,则解决了该问题(地址问题))
            已解决的符号表
     

    模板的分离编译:
        解决这种问题通过建立全新的"头文件"“.hpp”,相当于将头文件和源文件合并到一块了
    推荐方法:
    //a.hpp
    template<class T,class T>
    T& Add(T& left, T& right){
        return left+right;
    }
    //.cpp
    #include"a.hpp"
    int main(){
        Add(1,2);
        Add(1.0,3.0);
        return 0;
    }
    另一种方法(不推荐)
    a.cpp:
    T& Add(T& left,T& right){
        return left+right;
    }
    void testFun(){
        这种方法是通过下面代码进行模板的实例化,生成相应的函数,如果不给出实例化,由于每个源文件是单独编译的,因此对于test.cpp源文件中的Add(1,2)会生成未决符号表,在链接期间没有找到相应的函数,所以会报错:无法识别的外部符号
        Add(2,1);
        Add(2.0,1.0);
    }
    a.h
    template<class T,class T>
    T& Add(T& left,T& right);
     
    test.cpp:
    #include"a.h"
    int main(){
        Add(2,1);
        Add(2.0,1.0);
        return 0;
    }
  • 相关阅读:
    Centos6.5系统压力测试过程大量TIME_WAIT
    几种常用的数据库连接池
    weblogic弱密码检测
    ubuntu系统查看已安装的软件
    Flask Web中用MySQL代替SQLite
    SQLALCHEMY_TRACK_MODIFICATIONS adds significant异常的解决方法
    安装ipython时python setup.py egg_info错误的解决办法
    python manage.py runserver指定端口和ip
    Python连接mysql出错,_mysql_exceptions.OperationalError: (1045, "Access denied for user 'root'@'localhost' (using password: YES)")
    linux重启服务的脚本命令
  • 原文地址:https://www.cnblogs.com/love-you1314/p/10367276.html
Copyright © 2020-2023  润新知