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

怎么制作自己公司网站上海十大网站建设

怎么制作自己公司网站,上海十大网站建设,中国建设银行网站首页下载,关于网站建设项目收取费用文章目录 非类型模板类型形参非类型模板参数代码示例 **模板的特化**为什么要有模板的特化函数模板特化使用场景与示例函数模板特化的实现细节 类模板特化全特化示例 偏特化部分优化通过进一步限制模板参数进行特化偏特化为指针类型示例#xff1a;偏特化为引用类型示例#… 文章目录 非类型模板类型形参非类型模板参数代码示例 **模板的特化**为什么要有模板的特化函数模板特化使用场景与示例函数模板特化的实现细节 类模板特化全特化示例 偏特化部分优化通过进一步限制模板参数进行特化偏特化为指针类型示例偏特化为引用类型示例 特化测试结果分析 模板特化中的注意事项实例化时严格的匹配性指针特化时const的修饰问题为什么在参数列表使用constconst与指针修饰关系**指针本身是常量** (const在*之后)**指向的内容是常量** (const在*前面) 指针特化时const修饰的应用 已经特化的类中T表示为什么 模板的分离编译分离编译模式简介模板的分离编译分离编译测试原因解析C/C程序的编译链接原理为什么不能分离定义 非类型模板 模板参数分为类型形参和非类型形参 类型形参 类型形参即在模板初阶中所用的例如class A或typename A此类参数类型跟在class或typename后。 [C] 模版初阶-CSDN博客 非类型模板参数 非类型模板参数就是用一个常量作为类(函数)模板的一个参数在类(函数)模板中可将该参数当成常量来使用定义方法如下 templateclass T, size_t N 10注意 非类型模板参数只能是整型。浮点数、类对象以及字符串是不允许作为非类型模板参数的。非类型的模板参数必须在编译期就能确认结果原因看下文。 代码示例 templateint N class Array { public:int arr[N];// 其他方法 }; Array5 myArray; // 创建一个包含5个元素的数组对象模板的特化 为什么要有模板的特化 模板技术提供了强大的泛型编程能力使得我们能够编写与数据类型无关的代码从而提高代码的复用性和灵活性。然而在实际应用中有时需要对特定类型进行特殊处理这时就需要用到模板特化。 **注意**一般情况下如果函数模板遇到不能处理或者处理有误的类型为了实现简单通常都是将该函数直接给出 模板特化的出现是为了解决模板在处理某些特殊类型时可能遇到的问题。例如一个通用的比较函数模板可以比较大多数类型的数据但在遇到指针时仅比较指针的地址而不是指向的内容这就可能导致错误的结果。模板特化允许为特定类型提供定制的实现以解决这些特殊情况下的需求。 // 例如日期类中的函数模板的使用在使用指针比较的时候就会出现错误这时候就需要进行模板特化 templateclass T bool Less(T left, T right) {return left right; }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; // 可以比较结果错误当使用指针进行比较的时候比较的就是指针指向的地址而地址是从栈上向下申请所以不会按照原本日期类希望的排序方法进行排序。 此时就需要对模板进行特化。即在原模板类的基础上针对特殊类型所进行特殊化的实现方式。模板特化中分为函数模板特化与类模板特化 函数模板特化 函数模板特化用于为特定类型定制函数实现。它的典型用处是在普通模板无法满足某些类型需求时提供特定的功能。特化函数的签名必须与原模板函数完全一致。 函数模板的特化步骤 必须要先有一个基础的函数模板关键字template后面接一对空的尖括号函数名后跟一对尖括号尖括号中指定需要特化的类型函数形参表: 必须要和模板函数的基础参数类型完全相同如果不同编译器可能会报一些奇 怪的错误。 使用场景与示例 紧接上面的错误案例假设我们有一个通用的比较函数模板Less它比较两个对象的大小 templatetypename T bool Less(T left, T right) {return left right; }上述模板在大多数情况下都能正常工作但如果传入的是指针类型那么比较的将是指针的地址而非指向的对象。为了正确比较指针指向的内容我们需要对指针类型进行特化 template bool LessDate*(Date* left, Date* right) {return *left *right; }此特化版本用于比较指针指向的Date对象确保比较逻辑正确。 函数模板特化的实现细节 在实现函数模板特化时需要注意以下几点 特化声明模板特化的声明需要紧随template然后是函数签名特化的类型需要放在尖括号中。参数一致性特化函数的参数列表必须与原模板函数保持一致不能增加或减少参数也不能更改参数的顺序或类型。 **注意**推荐直接写一个函数实现特殊处理编译器在处理的时候会优先调用更匹配的。 类模板特化 类模板特化比函数模板特化更加复杂主要分为全特化和偏特化。类模板特化的主要作用是为特定类型提供定制的类定义和实现。 全特化 全特化是指将模板参数列表中的所有参数都具体化全特化版本中的所有参数都必须指定具体类型。 示例 假设我们有一个通用的数据存储类模板Data它可以存储两个不同类型的对象 templatetypename T1, typename T2 class Data { public:Data() { std::cout DataT1, T2 std::endl; } private:T1 _d1;T2 _d2; };我们可以为特定的类型组合如int和char进行全特化 template class Dataint, char { public:Data() { std::cout Dataint, char std::endl; } private:int _d1;char _d2; };在这个全特化版本中我们为Data类提供了一个int和一个char类型的特化实现。这意味着当我们创建Dataint, char类型的对象时将调用特化版本的构造函数。 偏特化 偏特化是部分特化的形式可以仅对部分模板参数进行特化。偏特化比全特化更灵活允许特化的同时保留一些模板参数。 偏特化中有两种表现方式部分特化、通过限制参数进行特化 部分优化 部分特化允许开发者针对特定的模板参数进行特化而其他模板参数保持泛型需要在template中声明。这样可以在不影响通用模板行为的情况下为某些特定类型或类型组合提供专门的实现。 示例 templatetypename T1, typename T2 class Pair { public:Pair(T1 first, T2 second) : first_(first), second_(second) {}T1 first() const { return first_; }T2 second() const { return second_; }private:T1 first_;T2 second_; };上述模板类是通用的可以存储任意类型的两个数据。然而如果我们需要对第一类型是int的情况进行特化可以使用部分特化 templatetypename T2 class Pairint, T2 { public:Pair(int first, T2 second) : first_(first), second_(second) {}int first() const { return first_; }T2 second() const { return second_; }void setFirst(int value) { first_ value; } // 额外的特化方法private:int first_;T2 second_; };在这个部分特化版本中我们特化了Pair模板的第一个类型为int第二个类型保持泛型。这样当Pairint, T2的对象创建时将调用这个特化版本而不是通用版本。 通过进一步限制模板参数进行特化 偏特化为指针类型示例 当需要模板参数为指针类型的时候可以对其进行特化以实现针对于指针的特定逻辑。这在需要对指针执行特定操作如解引用、比较等时尤为有用。 // 两个参数偏特化为指针类型 template typename T1, typename T2 class DataT1*, T2* { public:Data() { std::cout DataT1*, T2* std::endl; } private:T1 _d1;T2 _d2; };模板特化DataT1*, T2*这个偏特化版本对模板的两个参数T1和T2进行了特化使得它们必须是指针类型。实现细节在构造函数中打印了一条消息标识这是指针特化的版本。成员变量特化类中的成员变量依然是T1和T2类型不过它们实际上是指针指向的对象的类型。 偏特化为引用类型示例 对于引用类型的参数我们可以通过特化来处理那些需要传递引用的情况。这在需要修改外部对象或避免对象复制时非常有用。 // 两个参数偏特化为引用类型 template typename T1, typename T2 class DataT1, T2 { public:Data(const T1 d1, const T2 d2): _d1(d1), _d2(d2) {std::cout DataT1, T2 std::endl;} private:const T1 _d1;const T2 _d2; };模板特化DataT1, T2这个偏特化版本对模板的两个参数T1和T2进行了特化使得它们必须是引用类型。实现细节在构造函数中接受了T1和T2类型的引用并初始化类的成员变量。成员变量特化类中的成员变量是对传入对象的常量引用const T1和const T2这确保了数据不会被意外修改。 特化测试结果分析 void test2() {Datadouble, int d1; // 调用全特化的模板Dataint, double d2; // 调用基础的模板Dataint*, int* d3; // 调用特化的指针版本Dataint, int d4(1, 2); // 调用特化的引用版本 }Datadouble, int d1;调用了全特化模板因为参数类型既不是指针也不是引用。Dataint, double d2;同样调用全特化模板。Dataint*, int* d3;调用了特化的指针版本因为两个参数都是指针类型。Dataint, int d4(1, 2);调用了特化的引用版本因为两个参数是引用类型注意这里初始化引用类型参数时传递的是常量1和2这些字面量会被隐式转换为合适的引用类型。 模板特化中的注意事项 实例化时严格的匹配性 模板编程中模板实例化时的匹配性要求非常严格即使已经对模板进行了特化在实例化时也必须精确匹配到最合适的模板版本。这种严格的匹配性体现在以下几个方面 全特化指的是为特定类型组合提供一个完全定制化的实现。全特化要求在实例化时完全匹配所有模板参数类型只有在参数完全匹配时才会使用该特化版本。偏特化允许对部分模板参数进行特化同时保持其他参数的泛型性。在实例化时编译器会优先选择最匹配的特化版本。如果没有找到完全匹配的特化版本编译器才会退而求其次选择更加通用的版本。模板匹配顺序编译器在选择模板实例化时会按照以下优先顺序进行匹配 完全匹配的全特化优先级最高最匹配的偏特化最通用的模板 指针特化时const的修饰问题 为什么在参数列表使用const 防止修改传入的参数特化版本中的Date* const left和Date* const right通过使用const函数保证不会修改传入的指针变量本身的值即指针的指向保持不变。这是一种安全措施避免函数对外部数据的不必要的修改。 const与指针修饰关系 指针本身是常量 (const在*之后) 当const放在指针符号*之后时它修饰的是指针本身这意味着指针的值即它指向的内存地址不能被改变。但指针指向的对象的内容可以改变。 Date* const pDate;在这个例子中pDate是一个常量指针它指向一个Date类型的对象。pDate本身不能指向别处但是pDate指向的Date对象的内容是可以修改的。 通过特化时将**const**放在在*****之后即可解决在特化中的修饰关系。 指向的内容是常量 (const在*前面) 当const放在*前面时它修饰的是指针指向的对象这意味着不能通过这个指针修改指向的对象的内容但指针本身可以指向不同的对象。 const Date* pDate;在这个例子中pDate是一个指向Date对象的指针。虽然pDate本身可以指向不同的Date对象但不能通过pDate来修改它所指向的对象的内容。 指针特化时const修饰的应用 通用函数模板 templateclass T bool LessFunc(const T left, const T right) {return left right; }该函数模板中的const修饰的是传入的left和right不会被改变。 特化函数模板 template bool LessFuncDate*(Date* const left, Date* const right) {return *left *right; }**Date* const left** 和 **Date* const right**这两个参数都是指向Date对象的常量指针的引用。这意味着 指针本身不可改变函数内部不能改变left和right指向的地址与通用模板中的修饰目的相同。 为了保持与通用模板中const效果相同因此写为Date* const left。通用模板是为了是传入的数据不被修改而对于传入的指针来说**const**放在*****之后表示指针本身是常量。换句话说指针本身的地址不能改变也就是说一旦初始化后指针不能指向其他地址也就是传入的指针不能被修改了和通用模板实现的效果相同。 因此Date* const 的意思是“指向Date对象的常量指针的引用”。这个引用在函数内不会改变其所引用的指针对象也不能通过引用修改指针本身的指向。 已经特化的类中T表示为什么 在已经特化过的类中不管特化时是将原类型特化为指针类型或者引用类型之类的在类中使用T的时候一律会按照原类型进行使用也就是说如果在类中要用原类型的指针类型的话还是需要用T*。 如此表示在const修饰传参时也有用处例如上文所理解的LessFuncDate*(Date* const left, Date* const right)如果特化为指针的类中Date实际表示为Date*的话那么在修饰的时候究竟要如何修饰呢。此时就会产生语法与习惯上的矛盾所以将T直接作为原类型使用会更加方便与顺手。 模板的分离编译 分离编译模式简介 分离编译是软件工程中的一个基本概念它指的是将源代码分割成多个模块每个模块独立编译最后通过链接器将这些模块组合成最终的可执行文件。这种方式提高了编译的并行性同时也使得代码维护更加简单因为修改一个模块通常不会影响到其他模块的编译。 模板的分离编译 分离编译测试 我们有一个模板函数Add它的声明和定义被分别放在不同的文件中 // a.h templateclass T T Add(const T left, const T right);// a.cpp templateclass T T Add(const T left, const T right) {return left right; }在main.cpp中我们使用了Add函数的两个实例 #include a.hint main() {Add(1, 2); // 整数实例Add(1.0, 2.0); // 浮点数实例return 0; }此时当运行的时候会出现链接错误。 原因解析 C/C程序的编译链接原理 C/C程序的构建过程通常分为四个阶段预处理、编译、汇编和链接。 预处理预处理器处理#include指令和其他预处理器指令将头文件的内容插入到源文件中同时处理宏定义等。编译编译器将预处理后的源代码转换成汇编代码。在这个阶段编译器检查语法、词法和语义错误并且如果一切正确将代码转换成机器可以理解的指令集。汇编将汇编代码转换为机器代码的二进制形式。链接链接器将多个目标文件.obj和库文件链接起来解决符号引用问题生成最终的可执行文件。 为什么不能分离定义 **原因**模板实例化的代码并不是编译的时候在模板位置直接生成的而是在需要实例化的时候才会生成特定的具体代码。 实例化时机模板的实例化发生在编译器遇到模板函数或类的使用时。如果模板的定义不在编译器当前正在处理的编译单元中那么编译器无法知道如何实例化模板因此不会生成相应的函数代码。地址问题如你提到的例子当在a.cpp中没有Add模板的具体实例化代码时编译器不会生成对应的函数。而在main.obj中尝试使用Addint和Adddouble时链接器会在链接阶段寻找这些函数的地址但因为它们在编译时没有被生成所以链接器找不到这些地址导致链接错误。单定义规则One Definition RuleODRC的单定义规则要求每个非内联函数或变量在一个程序中只能有一个定义。模板的每次实例化都被视为一个独立的函数或类型定义这意味着每次实例化都必须在同一个编译单元中完成否则可能会违反ODR。**推荐做法**将模板的声明和定义放在同一个头文件中确保在任何包含该头文件的编译单元中都可以进行正确的实例化。
http://www.laogonggong.com/news/122075.html

相关文章:

  • 传媒建设网站网站营销不同阶段的网站分析目标
  • 新站如何提升网站权重微信 网站 优劣势
  • 外贸网站展示还是商城西安短视频运营公司
  • 网站建设 域名业务 邮箱潍坊市建设监理协会网站
  • 做订阅号要建立网站吗网店推广技巧
  • 陆金所网站开发二部网络销售公司经营范围
  • 营销网站建设收费标准制作头像
  • 重庆市住房和城乡建设部网站wordpress多久学会
  • 网站手机版下悬浮条怎么做网站建设 印花税
  • 襄阳网站推广优化技巧张店网站制作
  • 学生如何建设网站三门峡网站seo
  • 怎样推荐企业建设网站和互联网推广牡丹江哪个网络好
  • 宁波网站建设熊掌号怎样做软件网站
  • 新型城镇化建设网站网站建设的具体步骤
  • 淳安县住房和城乡建设局网站首页网上购物商城开发
  • 网站建设实训设计思想厦门编程培训机构
  • 北大学风建设网站浅析我国门户网站建设不足
  • 网站开发需要文章写的好吗开发网站建设
  • 高性能网站建设进阶指南pdf重庆做网站需要多少钱
  • 做调查的网站推广软文200字
  • 好品质高端网站设计厂家关键词采集软件
  • 网站建设算什么服务类型凡科建站的优势
  • 网站后台更改首页代码做外贸的物流网站
  • 搭建微信小程序需要什么seo的内容主要有哪些方面
  • 1m带宽可以建设电商网站吗网页设计作业心得
  • 什么做电子书下载网站软件平台架构
  • 企业电子商务网站深圳南山区住房和建设局网站
  • 北京学做网站青岛企业建站
  • 有没有专业做效果图的网站wordpress里买的模板可以改
  • 注册公司做网站app设计网站