google建站推广,北大青鸟网站开发,做网站怎么防止被黑,安陆网站摘要#xff1a;非类型模板参数#xff0c;类模板的特化#xff0c;模板的分离编译#xff0c;模板总结 前言#xff1a;C初阶终篇 1. 非类型模板参数
类型模板参数#xff1a;如下代码#xff0c;T 为模板的类型参数。
#define N 10
templateclass T
class …摘要非类型模板参数类模板的特化模板的分离编译模板总结 前言C初阶终篇 1. 非类型模板参数
类型模板参数如下代码T 为模板的类型参数。
#define N 10
templateclass T
class A
{
public:private:T* _a[N];
};void test_1()
{Aint a1;Adouble a2;
} 非类型模板参数对于上述代码如果我们想要对于不同的数据类型创建不同大小的_a数组呢例如对于 Aint 我们可能只要在其中存储10个 int 数据而 Adouble 我们可能需要在其中存储 100 个 double 类型的数据。所以对于这样的需求我们可以在模板中加入非类型模板参数来满足。
templateclass T, size_t N
class A
{
public:private:T* _a[N];
};void test_1()
{Aint, 10 a1;Adouble, 100 a2;
}
如上代码其中的 size_t N 即为模板中的非类型模板参数。 对于非类型模板参数有两个要求ps. char 也可以char 也是属于整型家族。另外C98只支持整型C98之后支持非整型 (补充) array
std::array
------------------------------------------
templateclass T, size_t N class array; cplusplus.com/reference/array/array/
array 的意义
C语言对于 int a[10]; a[15] 1; 不会检查越界a[15] 这个过程本质上是指针解引用。C对于 arrayint ,10 a2; a2[15] 1; 会检查越界这里的 a2[15] 本质上是函数调用所以可以在函数里进行执行越界检查。
C11初衷是希望大家用这个来代替静态数组但其实有更好的选择——vector。vector不仅对于越界设置了检查而且可以按需求进行初始化array不能按自己需求初始化 2. 模板的特化
特化针对某些类型做特殊处理
1类模板的特化 全特化
e.g.
上图所展示的即为类模板的全特化即针对 Data 类中 int 和 char 类型做特殊处理。
#includeiostreamtemplateclass T1, class T2
class Data
{
public:Data(){std::cout DataT1, T2 std::endl;}
private:T1 _d1;T2 _d2;
};template
class Dataint, char
{
public:Data(){std::cout Dataint, char std::endl;}
private:int _d1;char _d2;
};void test_2()
{Dataint, int d1;Dataint, char d2;
}int main()
{//test_1();test_2();return 0;
} 执行上述代码的结果为 DataT1, T2
Dataint, char 全特化即是将模板参数列表中所有的参数都确定化。 偏特化
(也称半特化) 偏特化任何针对模版参数进一步进行条件限制设计的特化版本。 针对上述代码所写的 Data 类所举出的例子
方式一将模板参数类表中的一部分参数特化。templateclass T1 , class T2class Data { …… };templateclass DataT1,double { …… }; 方式二针对模板参数更进一步的条件限制templateclass T1 , class T2class Data { …… };templateclass DataT1*,T2* { …… }; //这里的意思是只要的类型为指针例如int* , double* , char* , ……就调用这个特化出来的 class Data 2函数模板的特化
引入在 优先级队列 的文章中我们讨论了 对于 priority_queueDate* 如何通过仿函数来实现“自定义比较的规则”。这里我们可以选择通过函数模板的特化来实现。即对 class Less 实现特化。 但是对于上图所展示的代码class Less 的成员函数的参数列表按上图的写法会发生传值拷贝传值拷贝对于自定义类型可能会有深浅拷贝的问题。 因此参数列表建议改成 cosnt 引用然而这同时会给函数模板特化带来一些小问题。 如果你需要上图的代码↓
templateclass T
class Less
{bool operator()(const T left, const T right){return left right;}
};template
class LessDate*
{bool operator()(Date* const left, Date* const right){return *left *right;}
}; 3sum.
如果需要类模板可以使用特化而函数模板一般不使用特化更好的选择是实现重载。相当于自己实例化出来一个针对某个数据类型的函数而自己实例化的这个函数会与函数模板根据类型推导由编译器自动生成的实例化出来的函数构成重载。 3. 模板的分离编译
1函数模板 2类模板
类模板的分离编译一般是头文件声明成员(成员变量和成员函数)另外的 .cpp 文件中定义成员函数以这样的形式分离。同样会产生如函数模板分离编译的链接错误。
3sum.
如果声明和定义都在一个头文件里那么预处理展开之后就相当于 调用 与 定义 都在同一个文件里编译的时候就可以通过调用语句“告诉”编译器通过模板的定义怎样实例化。
ps.如果非得使模板的声明和定义分离可以不声明的同时定义但最好要把声明和定义放在一个文件里 4. 模板总结 【优点】 1. 模板复用了代码节省资源更快的迭代开发C的标准模板库(STL)因此而产生 2. 增强了代码的灵活性。 【缺陷】 1. 模板会导致代码膨胀问题也会导致编译时间变长 2. 出现模板编译错误时错误信息非常凌乱不易定位错误。 END