个人网站毕业设计论文wordpress plugins php speedy
个人网站毕业设计论文,wordpress plugins php speedy,在线做效果图有哪些网站,wordpress 文章模版结束了常用容器的介绍#xff0c;今天继续模版内容的讲解#xff1a; 文章目录 1.非类型模版参数2.模板的特化2.1模版特化引入和概念2.2函数模版特化2.3类模板特化2.3.1全特化2.3.1偏特化 3. 模板分离编译3.1分离编译概念3.2**模板的分离编译**分析原因 1.非类型模版参数 模板…结束了常用容器的介绍今天继续模版内容的讲解 文章目录 1.非类型模版参数2.模板的特化2.1模版特化引入和概念2.2函数模版特化2.3类模板特化2.3.1全特化2.3.1偏特化 3. 模板分离编译3.1分离编译概念3.2**模板的分离编译**分析原因 1.非类型模版参数 模板参数可以大致分为分类类型形参与非类型形参。 类型形参即出现在模板参数列表中跟在class或者typename之类的参数类型名称 非类型形参就是用一个常量作为类(函数)模板的一个参数在类(函数)模板中可将该参数当成常量来使用 #includeiostream
using namespace std;templateclass T,int N
class MyArray
{
public:MyArray() {for (int i 0; i N; i) {_arr[i] i;}}void print(){for (int i 0; i N; i){cout _arr[i] ;}}
private:T _arr[N];//定义一个静态数组
};void test1()
{MyArrayint, 10 my;my.print();
}int main()
{test1();return 0;
}注意 浮点数、类对象以及字符串是不允许作为非类型模板参数的。 非类型的模板参数必须在编译期就能确认结果。 2.模板的特化
2.1模版特化引入和概念
通常情况下使用模板可以实现一些与类型无关的代码但对于一些特殊类型的可能会得到一些错误的结果需要特殊处理。如下
templateclass T
bool Less(T left, T right)
{return left right;
}void test2()
{cout Less(1, 2) endl; //结果正确double d1 1.1;double d2 2.2;cout Less(d1, d2) endl; //结果正确double* p1 d1;double* p2 d2;cout Less(p1, p2) endl; //结果错误
}int main()
{test2();return 0;
}可以看到Less绝对多数情况下都可以正常比较(前两者)但是在特殊场景下最后一个就得到错误的结果。上述示例中p1指向的d1显然小于p2指向的d2对象但是Less内部并没有比较p1和p2指向的对象内容而比较的是p1和p2指针的地址的大小这就无法达到预期而错误。 此时就需要对模板进行特化。即在原模板类的基础上针对特殊类型所进行特殊化的实现方式。模板特化中分为函数模板特化与类模板特化 2.2函数模版特化
函数模板的特化步骤 必须要先有一个基础的函数模板 关键字template后面接一对空的尖括号 函数名后跟一对尖括号尖括号中指定需要特化的类型 函数形参表: 必须要和模板函数的基础参数类型完全相同 解决上述问题 templateclass T
bool Less(T left, T right)
{return left right;
}
// 对Less函数模板进行特化
template
bool Lessdouble*(double* a, double* b)//函数名后跟一对尖括号
{return *a *b;
}void test2()
{cout Less(1, 2) endl; //结果正确double d1 1.1;double d2 2.2;cout Less(d1, d2) endl; //结果正确double* p1 d1;double* p2 d2;cout Less(p1, p2) endl; //结果错误
}int main()
{test2();return 0;
}同时我们也不仅可以利用特化解决直接重载也是可以的(直接给出针对这个类型的函数) bool Less(double* left, double* right)
{
return *left *right;
}该种实现简单明了代码的可读性高容易书写因为对于一些参数类型复杂的函数模板特化时特别给出因此函数模板不建议特化。 2.3类模板特化
2.3.1全特化 全特化即是将模板参数列表中所有的参数都确定化 templateclass T1, class T2
class Data
{
public:Data() { cout DataT1, T2 endl; }
private:T1 _d1;T2 _d2;
};template//这是全特化
class Dataint, double
{
public:Data() { cout Dataint, double endl;}
private:int _d1;double _d2;
};void test3()
{Dataint,int d1;Dataint,double d2;
}int main()
{test3();return 0;
}2.3.1偏特化
偏特化有以下两种表现方式
部分特化将模板参数类表中的一部分参数特化。
templateclass T1, class T2
class Data
{
public:Data() { cout 正常没特化DataT1, T2 endl; }
private:T1 _d1;T2 _d2;
};template//这是全特化
class Dataint, double
{
public:Data() { cout 全特化Dataint, double endl;}
private:int _d1;double _d2;
};templateclass T//这是偏特化
class DataT, double
{
public:Data(){cout 偏特化DataT, double endl;}
private:int _d1;double _d2;
};void test3()
{Dataint,int d1;Dataint,double d2;Datachar,double d3;
}int main()
{test3();return 0;
}当既满足偏特化又满足全特化会作何选择呢 选择全特化偏特化还需要参数匹配还需要实例化一部分参数我们直接用现成的全特化 参数更进一步的限制偏特化并不仅仅是指特化部分参数而是针对模板参数更进一步的条件限制所设计出来的一个特化版本。
templateclass T1,class T2//这是偏特化另一情况进行限制这里限制为指针
class DataT1*, T2*
{
public:Data(){cout 偏特化DataT1*, T2* endl;}
private:T1 _d1;T2 _d2;
};templateclass T1, class T2//这是偏特化另一情况进行限制这里限制为指针
class DataT1, T2
{
public:Data(){cout 偏特化DataT1, T2 endl;}
};void test3()
{Dataint*,int* d1;Dataint,double d2;
}int main()
{test3();return 0;
}3. 模板分离编译
3.1分离编译概念 一个项目我们通常会用若干个源文件共同实现而每个源文件单独编译生成目标文件最后将所有目标文件链接起来形成单一的可执行文件的过程称为分离编译模式 3.2模板的分离编译 在之前的各种使用中我们没有过把模版声明和定义分离放在两个文件里 如果分离 一运行就发现找不到这个函数 分析原因
我们知道C/C程序的运行一般包括了预处理、编译、汇编和链接等步骤。
预处理Preprocessing 这个阶段会处理源代码中的预处理指令比如#include、#define等将宏展开、头文件包含等操作。预处理的结果是生成一个纯粹的C源文件没有预处理指令。编译Compilation 编译器将预处理后的源代码翻译成汇编语言。在这个阶段编译器会进行词法、语法、语义分析并生成相应的汇编代码。每个源文件都会被单独编译生成相应的目标文件Object File通常以.obj、.o等为扩展名。汇编Assembly 汇编器将汇编代码转换成机器语言的目标文件。链接Linking 链接器将多个目标文件、库文件以及系统的一些运行时代码合并成一个可执行文件。链接的过程包括地址解析、符号解析、重定向等步骤确保各个目标文件中的符号能够正确关联。 从main函数开始执行我们遇到了Add1,2因为包含了.h头文件有声明我们会到链接部分找实现但是在另一方文件的实现不知道我进行了实例化也就没有进行实例化所以链接后找不到 模板在使用时需要在编译阶段进行具体实例化而编译器需要在编译的时候能够看到模板的完整定义以便正确生成代码。如果将模板的声明和定义分离成不同的文件编译器就无法在编译阶段得知模板的具体实现 模板的编译过程通常包含两个主要阶段模板的定义和模板的实例化。 模板定义 模板定义包括模板的声明和实现。这一部分通常包含在头文件.h或.hpp中并在源文件.cpp中包含。在编译过程的第一阶段编译器会处理源文件和头文件但并不会生成实际的代码。模板实例化 在使用模板的源文件中当实际用到模板的具体类型时编译器会进行模板实例化。这时编译器需要看到模板的完整定义以便生成相应类型的实际代码。这个阶段实际上是对模板进行展开生成模板特定实例的代码。 由于模板实例化需要在编译时完成模板的定义必须在使用它的源文件中可见。如果将模板的声明和实现分离到不同的文件编译器在实例化时就无法找到完整的定义从而导致编译错误
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/88177.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!