【C++】模板进阶--保姆级解析(什么是非类型模板参数?什么是模板的特化?模板的特化如何应用?)

2024-07-08 1682阅读

目录

一、前言

二、什么是C++模板? 

💦泛型编程的思想  

💦C++模板的分类 

三、非类型模板参数

⚡问题引入⚡   

⚡非类型模板参数的使用⚡    

🔥非类型模板参数的定义

🔥非类型模板参数的两种类型

🔥非类型模板参数的使用规则

⚡问题的解决⚡   

⚡非类型模板参数的实例应用⚡    

四、模板的特化 

💧 概念

💧 函数模板特化 

💧 类模板特化 

🔥全特化🔥

🔥偏特化🔥 

💧模板特化的应用示例 

五、总结 

六、共勉 


一、前言

       在我们学习C++时,常会用到函数重载。而函数重载,通常会需要我们编写较为重复的代码,这就显得臃肿,且效率低下。重载的函数仅仅只是类型不同,代码的复用率比较低,只要有新类型出现时,就需要增加对应的函数。此外,代码的可维护性比较低,一个出错可能会导致所有的重载均出错。

       那么,模板的出现,就让这些问题有了解决方案,在之前的文章中已经详细的讲解了C++的 ----- 模板初阶,所以本次博客将为大家详细的讲解C++的模板进阶!!

二、什么是C++模板? 

        程序设计中经常会用到一些程序实体:它们的实现和所完成的功能基本相同,不同的仅 仅是所涉及的数据类型不同。而模板正是一种专门处理不同数据类型的机制。

       模板------是泛型程序设计的基础(泛型generic type——通用类型之意)。

 

        函数、类以及类继承为程序的代码复用提供了基本手段,还有一种代码复用途径——类属类型(泛型),利用它可以给一段代码设置一些取值为类型的参数(注意:这些参数 的值是类型,而不是某类型的数据),通过给这些参数提供一些类型来得到针对不同类 型的代码。

💦泛型编程的思想  

  首先我们来看一下下面这三个函数,如果学习过了C++函数重载 和 C++引用 的话,就可以知道下面这三个函数是可以共存的,而且传值会很方便 

void Swap(int& left, int& right)
{
	int temp = left;
	left = right;
	right = temp;
}
void Swap(double& left, double& right)
{
	double temp = left;
	left = right;
	right = temp;
}
void Swap(char& left, char& right)
{
	char temp = left;
	left = right;
	right = temp;
}

但是真的很方便吗?这里只有三种类型的数据需要交换,若是我们需要增加交换的数据呢?再CV然后写一个函数吗?

这肯定是不现实的,所以很明显函数重载虽然可以实现,但是有一下几个不好的地方: 

  • 重载的函数仅仅是类型不同,代码复用率比较低,只要有新类型出现时,就需要用户自己增加对应的函数
  • 代码的可维护性比较低,一个出错可能所有的重载均出错

    那是否能做到这么一点,告诉编译器一个模子,让编译器根据不同的类型利用该模子来生成代码 

    【C++】模板进阶--保姆级解析(什么是非类型模板参数?什么是模板的特化?模板的特化如何应用?)


     ⭐总结: 

            所以,总结上面的这么一个技术,C++的祖师爷呢就想到了【模版】这个东西,告诉编译器一个模子,然后其余的工作交给它来完成,根据不同的需求生成不同的代码 

     这就是👉泛型编程:编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础


    💦C++模板的分类 

    1️⃣: 函数模板(function tempalte):使用泛型参数的函数(function with generic parameters)
    2️⃣:类模板(class template):使用泛型参数的类(class with generic parameters) 

    更加具体 模板初阶知识 大家这一去看看之前的文章 ----- 模板初阶

    本篇文章主要讲解 模板的高阶操作:非类型模板参数、全特化、偏特化等,以及关于模板声明与定义不能分离(在两个不同的文件中)的问题。


    三、非类型模板参数

         之前所使用的模板参数都是用来匹配不同的类型,如 int、double、Date 等,模板参数除了可以匹配类型外,还可以匹配常量(非类型),完成如数组、位图等结构的大小确定 

    ⚡问题引入⚡   


     问题: 

            假设我现在自定义了一个静态栈,栈的大小设置为100。然后我构建了一个int 的类型的栈st1,和一个double 类型的栈st2。那么我希望stl 的大小为100,st2 的大小为500,能不能实现呢?

     --------------  肯定是不能的! ! !


     如下面这个例子所示: 

    #define N 100
    // 静态栈
    template
    class Stack
    {
    private:
    	int _a[N];
    	int _top;
    };
    int main()
    {
    	Stack st1;
    	Stack st1;
    	return 0;
    }
    

    【C++】模板进阶--保姆级解析(什么是非类型模板参数?什么是模板的特化?模板的特化如何应用?)

    • 从上图 可以发现,栈 的两个对象 的大小都为 100。 

       那有什么办法 可以解决这个问题呢?

      这个时候,就要引出 ---- 非类型模板参数 


      ⚡非类型模板参数的使用⚡    

       我们知道模板参数分为 : 类型形参 与 非类型形参 

      • 类型模板形参 : 出现在模板参数列表中,跟在 class 或者 typename 类之后的参数类型名称。
        template   // T 为模板参数中的 ---------- 类型模板形参
        • 非类型模板形参 : 就是用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当成常量来使用。
          template   // N 为模板参数中的 ------- 非类型模板形参

          🔥非类型模板参数的定义

          在定义模板参数时,可以不再使用 class 或 typename,而是直接使用具体的类型,如 size_t,此时称为 非类型模板参数 

          注:非类型模板参数必须为常量,即在编译阶段确定值 


          🔥非类型模板参数的两种类型

          1️⃣: 利用 非类型模板参数 定义一个大小可以自由调整的 整型数组 类 

          template
          class arr
          {
          public:
              T& operator[](size_t pos)
          	{
          		assert(pos >= 0 && pos 
VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]