c++----模版进阶
c++----模版初阶:http://t.csdnimg.cn/PiYoD
一.非类型模版参数
模板参数除了可以是类型,还可以是常量。
例如:
这样就可以在类中使用这个n常量。
---------------------------------------------------------------------------------------------------------------------------------
使用时需要注意的几点:
1. 在c++20标准之前,n的类型只能是整形。在c++20及之后,n可以是所有内置类型。但是哪个标准中n都不可以是自定义类型.
2. n是右值,也就是说它不是变量而是常量,所以你不能再类中修改它。
---------------------------------------------------------------------------------------------------------------------------------
非类型模版参数的应用:
(1)
在标准库中的 arry 数组类的设计就引用了非类型模版参数,用于指定数组所开空间的大小。
如图,在栈上开辟了10个int大小的空间。
---------------------------------------------------------------------------------------------------------------------------------
说到arry,这里有一些补充:
<1>arry在栈上开辟空间,而vector在堆上开辟
<2>以C语言方式开辟数组(int arr[10]) 是有缺陷的,因为编译器对于该数组的越界检查是抽查机制,只会检查临近数组范围的标志位是否被修改,所以如果越界一两个位置修改数据是会报错,但是越界很多修改数据就不会报错了,并且如果只读数据的话上述两种情况都是不报错的。
编译器不同有可能arr[20] = 10 也会检查报错,但是大体上这种方式是欠缺的。
而arry无论是读数据还是写数据都会进行严格的越界检查,这是其优势(vector也是这样)。
二.typename指定类型
这样的代码会报错:
原因是,在编译过程中,并不会实例化模版,所以此时vector<T>具体内容还不确定是什么, vector<T>::iterator 有可能取出来的是迭代器类型,也有可能取出来的是可访问变量,编译器不敢确认,这时只要在前面加上typename 说明这是一个类型名即可:
---------------------------------------------------------------------------------------------------------------------------------
三.特化
特化就是针对特殊类型使其走不同于正常情况的逻辑,特化有两种:函数模板特化和类模板特化。
1.函数模板特化·
这是一个比较类的模板函数,看起来不错,但如果我想要这样:即使给compare传地址,也能正常比较数字大小,原来的逻辑显然不行,这是我们可以这样:
下面的compare就是上面的compare的特化,只要给compare传入的参数类型是int*,就会走下面的逻辑。从这个例子我们也可以看到函数模板特化的形式。
特化步骤:
1. 必须要先有一个基础的函数模板
2. 关键字template后面接一对空的尖括号<>
3. 函数名后跟一对尖括号,尖括号中指定需要特化的类型
4. 函数形参表: 必须要和模板函数的基础参数类型完全相同,如果不同编译器可能会报一些奇怪的错误。
---------------------------------------------------------------------------------------------------------------------------------
函数模板特化的坑:
为什么会报错呢?
原函数模板中,const修饰的是形参,而特化出来的函数中const修饰的是形参指向的内容,所以可以认为两者参数不一致,那么下面的compare也就不算上面的compare的特化了。
解决方法:
---------------------------------------------------------------------------------------------------------------------------------
2.类模板特化之全特化
全特化是指特化时把类的所有模板参数都确定。看下面例子:
从这个例子也可以看出类模板全特化的形式。
---------------------------------------------------------------------------------------------------------------------------------
3.类模板特化之偏特化
偏特化是指只确定类模版参数的一部分。看下面例子
只要第二个模版参数传的是int就调用特化,从这个例子也可以看出类模板偏特化的形式。
---------------------------------------------------------------------------------------------------------------------------------
上面只是偏特化的一种形式,下面是偏特化的另一种体现:
上面的特化不确定模板参数的具体类型,而是限制了:只要传入的两个模板参数都是指针类型(也可以限制成引用;甚至一个限制引用,另一个限制成指针),那么就走特化。
特别注意:在上面例子的特化中,T1和T2的类型不是指针类型,而是指针指向的数据类型。比如
A<int*, int*> x1;走的是特化,但是实例化后T1和T2是int类型,而不是int *;
原文地址:https://blog.csdn.net/2302_80221042/article/details/140632777
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!