模板

    xiaoxiao2023-10-03  158

    泛型编程

    编写与类型无关的通用代码,是代码复用的一种手段,模板是泛型编程的基础

    模板

    模板分为函数模板和类模板

    优点

    复用代码,节省资源,更快的迭代开发增强了代码堆的灵活性

    缺点

    模板会导致代码膨胀,也可能导致编译时间变长出现模板编译错误时,错误信息非常凌乱,不易定位错误

    函数模板

    函数怒班代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本

    格式

    template<typename T1, typename T2, ..., typename Tn> 返回值类型 函数名(参数列表){} //typename是定义模板的关键字,也可以使用class,不能用struct

    原理

    模板不是函数,是编译器产生特定具体类型函数的模具,在编译阶段,编译器需要根据传入的实参类型来推演生成对应类型的函数

    函数模板实例化

    隐式实例化:编译器根据实参推演模板参数的实际类型,在模板中,编译器不会进行类型转换,所以同一个参数T的类型必须相同显式实例化:在函数名后的<>中指定模板参数的实际类型,如果不匹配,编译器会进行隐式转换,转换失败编译器将会报错

    函数模板匹配原则

    非函数模板可以和同名的函数模板同时存在,该函数模板可以被实例化为这个非函数模板非函数模板与其同名的函数模板,编译器在调用时会优先调用非函数模板,如果函数模板可以产生一个具有更好的品牌函数,那么调用函数模板函数模板不允许类型转换,普通函数可以进行类型转换

    类模板

    格式

    template<class T1, class T2, ..., class Tn> class 类模板名{}; //类模板中的函数放在类外进行定义时,需要加模板参数列表

    类模板实例化

    在类模板名后的<>中指定模板参数的实际类型,类模板名字不是真正的类,实例化的结果才是真正的类

    模板参数

    类型形参:在参数列表中用class或typename修饰的参数类型非类型形参:用常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当成常量来使用,非类型模板参数必须在编译时期确认结果,浮点数、类对象、字符串不允许作为非类型模板参数

    模板特化

    在原模板的基础上,对特殊类型进行特殊化称为模板特化,模板特化分为函数模板特化和类模板特化

    函数模板特化

    必须有基础的函数模板 template<class T> bool IsEqual(T& left, T& right){} 函数模板的特化 template<> //函数形参表必须和函数模板的基础参数类型相同,如果不同编译器可能会报错 bool IsEqual<char*>(cahr*& left, char*& right){} 我们一般为实现简单,直接定义一个同名的非函数模板 bool IsEqual(cahr* left, char* right){}

    类模板特化

    必须有基础的类模板

    template <class T1, class T2> class Data{};

    全特化:将模板参数列表中的所有参数都确定化

    template <> class Data<char, int>{};

    偏特化

    部分特化:将参数列表的一部分参数特化 template <class T1> class Data<T1, int>{}; 参数进一步限制:对模板参数进一步条件限制 //偏特化为指针类型 template <class T1, class T2> class Data<T1*, T2*>{}; //偏特化为引用类型 template <class T1, class T2> class Data<T1&, T2&>{};

    模板分离编译

    分离编译

    一个程序(项目)有若干个源文件共同实现,而每个源文件单独编生成目标文件,最后将所有目标文件链接起来形成单一的可执行过程

    模板分离编译方式

    将声明和定义放到一个文件.hpp或.h,推荐使用模板定义的位置显式实例化,不实用,不推荐

    最新回复(0)