自学内容网 自学内容网

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)!