当前位置: 首页 > news >正文

做智能网站软件在线3d设计家官网

做智能网站软件,在线3d设计家官网,制作网站找哪家好,网站附件做外链前言 在我们平时的代码中经常会有不同类型的变量去执行效果差不多的函数。比如#xff1a;swap(交换)#xff0c;sort(排序)。这些函数里其实会有大部分重复的段落#xff0c;在这种情况下我们会使用重载函数#xff0c;但是函数重载会有如下的问题#xff1a; 1. 重载的函… 前言 在我们平时的代码中经常会有不同类型的变量去执行效果差不多的函数。比如swap(交换)sort(排序)。这些函数里其实会有大部分重复的段落在这种情况下我们会使用重载函数但是函数重载会有如下的问题 1. 重载的函数仅仅是类型不同代码复用率比较低只要有新类型出现时就需要用户自己增加对应的函数。 2. 代码的可维护性比较低一个出错可能所有的重载均出错。 那能否告诉编译器一个模子让编译器根据不同的类型利用该模子来生成代码呢 一、函数模板 1.1概念 函数模板代表了一个函数家族该函数模板与类型无关在使用时被参数化根据实参类型产生函数的特定类型版本。 1.2函数模板格式 templatetypename T1, typename T2,......,typename Tn 返回值类型 函数名(参数列表){} ​templatetypename T void Swap( T left, T right) {T temp left;left right;right temp; } //可识别不同的同种类型交换例char与charint与intdouble与double 注意typename是用来定义模板参数关键字也可以使用class(切记不能使用struct代替class) 1.3函数模板的实例化 用不同类型的参数使用函数模板时称为函数模板的实例化。模板参数实例化分为隐式实例化和显式实例化。 隐式实例化让编译器根据实参推断模板参数的实际类型 适用环境交换类型为同一类 在编译器编译阶段对于模板函数的使用编译器需要根据传入的实参类型来推演生成对应类型的函数以供调用。比如当用double类型使用函数模板时编译器通过对实参类型的推演将T确定为double类型然后产生一份专门处理double类型的代码对于字符类型也是如此。 不适用情况一个模板传两种类型 templateclass T T Add(const T left, const T right) {return left right; } int main() {int a1 10, a2 20;double d1 10.0, d2 20.0;Add(a1, a2);Add(d1, d2);return 0; } 分析该语句不能通过编译因为在编译期间当编译器看到该实例化时需要推演其实参类型通过实参a1将T推演为int通过实参d1将T推演为double类型但模板参数列表中只有一个T编译器无法确定此处到底该将T确定为int 或者 double类型而报错。 注意在模板中编译器一般不会进行类型转换操作因为一旦转化出问题编译器就需要背黑锅。 Add(a1, d1); 此时有两种处理方式 1. 用户自己来强制转化 2. 使用显式实例化。 显示实例化在函数名后的中指定模板参数的实际类型 int main(void) {int a 10;double b 20.0;// 显式实例化Addint(a, b);return 0; } 如果类型不匹配编译器会尝试进行隐式类型转换如果无法转换成功编译器将会报错。 1.4函数模板的匹配原则 一个非模板函数可以和一个同名的函数模板同时存在而且该函数模板还可以被实例化为这个非模板函数对于非模板函数和同名函数模板如果其他条件都相同在调动时会优先调用非模板函数而不会从该模 板产生出一个实例。如果模板可以产生一个具有更好匹配的函数 那么将选择模板模板函数不允许自动类型转换但普通函数可以进行自动类型转换。 简单来说就是函数先找现成的然后再去模板匹配。 二、类模板 2.1类模板的格式 templateclass T1, class T2, ..., class Tn class 类模板名 {// 类内成员定义 }; 2.2类模板的实例化 类模板实例化与函数模板实例化不同类模板实例化需要在类模板名字后跟然后将实例化的类型放在中即可类模板名字不是真正的类而实例化的结果才是真正的类。 Vectorint s1; Vectordouble s2; // Vector 类名 Vectorint 才是类型 注意区分 在类中类名等同于类型在类模板中类型是类型类名是类名 例如在下面代码中类模板中函数放在类外进行定义时需要加模板参数列表在访问类模板时要用VectorT类型而不是Vector类名 三、非类型模板参数 在c语言中我们通常会使用宏而常用类的c中推出了非类型模板参数。比如我们在创建一个array时会在创建时确定他的大小等等。 模板参数分类类型形参与非类型形参。 类型形参即出现在模板参数列表中跟在class或者typename之类的参数类型名称。 非类型形参就是用一个常量作为类(函数)模板的一个参数在类(函数)模板中可将该参数当成常量来使用。 // 定义一个模板类型的静态数组templateclass T, size_t N 10class array{public:T operator[](size_t index){return _array[index];}const T operator[](size_t index)const{return _array[index];}size_t size()const{return _size;}bool empty()const{return 0 _size;}private:T _array[N];size_t _size;}注意 1. 浮点数、类对象以及字符串是不允许作为非类型模板参数的。 2. 非类型的模板参数必须在编译期就能确认结果。 四、模板的特化 4.1概念 通常情况下使用模板可以实现一些与类型无关的代码但对于一些特殊类型的可能会得到一些错误的结果需要特殊处理比如实现了一个专门用来进行小于比较的函数模板。日期类的比较或者传入指向数值的指针他们的比较方式是编译器所不了解的。 // 函数模板 -- 参数匹配 templateclass T bool Less(T left, T right) {return left right; } int main() {cout Less(1, 2) endl; // 可以比较结果正确Date d1(2022, 7, 7);Date d2(2022, 7, 8);cout Less(d1, d2) endl; // 可以比较结果正确Date* p1 d1;Date* p2 d2;cout Less(p1, p2) endl; // 可以比较结果错误return 0; } 可以看到Less绝对多数情况下都可以正常比较但是在特殊场景下就得到错误的结果。上述示例中p1指向的d1显然小于p2指向的d2对象但是Less内部并没有比较p1和p2指向的对象内容而比较的是p1和p2指针的地址这就无法达到预期而错误。 此时就需要对模板进行特化。即在原模板类的基础上针对特殊类型所进行特殊化的实现方式。模板特化中分为函数模板特化与类模板特化. 4.2函数模板特化 函数模板的特化步骤 1. 必须要先有一个基础的函数模板 2. 关键字template后面接一对空的尖括号 3. 函数名后跟一对尖括号尖括号中指定需要特化的类型 4. 函数形参表: 必须要和模板函数的基础参数类型完全相同如果不同编译器可能会报一些奇怪的错误。 // 函数模板 -- 参数匹配 templateclass T bool Less(T left, T right) {return left right; } // 对Less函数模板进行特化 template bool LessDate*(Date* left, Date* right) {return *left *right; } int main() {cout Less(1, 2) endl;Date d1(2022, 7, 7);Date d2(2022, 7, 8);cout Less(d1, d2) endl;Date* p1 d1;Date* p2 d2;cout Less(p1, p2) endl; // 调用特化之后的版本而不走模板生成了return 0; }注意一般情况下如果函数模板遇到不能处理或者处理有误的类型为了实现简单通常都是将该函数直接给出。 bool Less(Date* left, Date* right) {return *left *right; } 这时就遵循优先匹配原则。而且该种实现简单明了代码的可读性高容易书写因为对于一些参数类型复杂的函数模板特化时特别给出因此函数模板不建议特化。 4.3类模板的特化 全特化 全特化即是将模板参数列表中所有的参数都确定化。 templateclass T1, class T2 class Data { public:Data() {coutDataT1, T2 endl;} private:T1 _d1;T2 _d2; }; template class Dataint, char { public:Data() {coutDataint, char endl;} private:int _d1;char _d2; };void TestVector() {Dataint, int d1;Dataint, char d2; } 偏特化 偏特化任何针对模版参数进一步进行条件限制设计的特化版本。比如对于以下模板类 templateclass T1, class T2 class Data { public:Data() {coutDataT1, T2 endl;} private:T1 _d1;T2 _d2; }; 偏特化有以下两种表现方式 部分特化        将模板参数类表中的一部分参数特化。 // 将第二个参数特化为int template class T1 class DataT1, int { public:Data() {coutDataT1, int endl;} private:T1 _d1;int _d2; }; 参数更进一步的限制 偏特化并不仅仅是指特化部分参数而是针对模板参数更进一步的条件限制所设计出来的一个特化版本 //两个参数偏特化为指针类型 template typename T1, typename T2 class Data T1*, T2* { public:Data() {coutDataT1*, T2* endl;}private:T1 _d1;T2 _d2; }; //两个参数偏特化为引用类型 template typename T1, typename T2 class Data T1, T2 { public:Data(const T1 d1, const T2 d2): _d1(d1), _d2(d2){coutDataT1, T2 endl;}private:const T1 _d1;const T2 _d2; }; void test2 () {Datadouble , int d1; // 调用特化的int版本Dataint , double d2; // 调用基础的模板 Dataint *, int* d3; // 调用特化的指针版本Dataint, int d4(1, 2); // 调用特化的指针版本 } 五、模板分离编译  5.1什么是分离编译 一个程序项目由若干个源文件共同实现而每个源文件单独编译生成目标文件最后将所有目标文件链接起来形成单一的可执行文件的过程称为分离编译模式。 5.2 分离编译的方法 1. 将声明和定义放到一个文件 xxx.hpp 里面或者xxx.h其实也是可以的。推荐使用这种。 2. 模板定义的位置显式实例化。这种方法不实用不推荐使用。 【分离编译扩展阅读】 http://blog.csdn.net/pongba/article/details/19130 六、模板总结 【优点】 1. 模板复用了代码节省资源更快的迭代开发C的标准模板库(STL)因此而产生 2. 增强了代码的灵活性 【缺陷】 1. 模板会导致代码膨胀问题也会导致编译时间变长 2. 出现模板编译错误时错误信息非常凌乱不易定位错误
http://wiki.neutronadmin.com/news/400219/

相关文章:

  • 如何做伪原创文章网站西安app制作开发公司
  • 护肤品网站建设分析综合门户网站有哪些
  • dw如何用表格来做网站网站宽度 像素
  • 设计和建设企业网站心得和体会wordpress 盈利
  • 对于网站运营应该如何做电商平台网站开发
  • 住房和城乡建设部网站唐山辽宁建设厅网站
  • seo综合查询站长工具怎么用商城展示网站
  • 小说网页网站建设怎么做兼职网站吗
  • 视频网站直播如何做网络服务主要包括什么
  • 建设网站的意义 作用是什么意思自贡市网站建设
  • 厦门网站建设培训学校企业免费网站设计公司
  • 请说明网站建设的一般过程包括哪些网站怎么更新
  • 简述网站开发的几个步骤贵港网站建设培训
  • 公司关于网站建设的通知大连建设工程招标信息网官网
  • 叙述一个网站的建设过程wordpress知名网站
  • 1m带宽网站支持多少人同时在线大型网站建设制作平台
  • 2017两学一做网站织梦做小游戏网站
  • 通州免费网站建设在线平面设计兼职
  • 专门做行业分析的网站网站综合营销方案设计
  • 鞍山便民信息平台南沙网站建设优化
  • 网站横幅怎么做自己做个网站要多少钱
  • 网站开发工程师需要会写什么如何做外贸营销型网站推广
  • 哪做网站比较便宜最专业的网站建设价格
  • dedecms做的网站_网站中的图片总是被同一ip恶意点击企业邮箱域名解析
  • 深圳网站 制作信科便宜建设工商联网站的意义
  • 网站商城具有哪些功能模块如何做线上营销
  • 注册公司网站广州外贸网站咨询
  • 网站建设的经验做法番禺网站开发报价
  • 把给公司做的设计放到自己的网站上沈阳网站建设 熊掌号
  • 用php做购物网站案例江西萍乡做网站公司