• 【C++笔记】模板进阶


    一、非类型模板参数

    我们之前学过的模板虽然能很好地帮我们实现泛型编程,比如我们可以让一个栈存储int类型的数据,一个栈存储double类型的数据:

    template <class T>
    class Stack {
    public :
    	Stack() {
    		cout << "Stack()" << endl;
    	}
    	~Stack() {
    		cout << "~Stack()" << endl;
    	}
    private :
    	T* _data;
    }
    
    int main() {
    	Stack<int> st1;
    	Stack<double> st2;
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    但是如果我们想实现两个静态的栈,一个容量为10,另个一容量为100,那就没有办法了。

    对此,C++又引入了一个非类型模板参数

    template <class T, size_t N>
    class Stack {
    public:
    	Stack() {
    		cout << "Stack()" << endl;
    	}
    	~Stack() {
    		cout << "~Stack()" << endl;
    	}
    private:
    	T data[N];
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    这样我们就可以在实例化的时候给上对应的容量了:

    int main() {
    	Stack<int, 10> st1;
    	Stack<double, 100> st2;
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    需要注意的是
    非类型模板参数一定要是常量,不能是变量:
    在这里插入图片描述
    非类型模板参数一定要是整型(包括整型家族的所有成员char、short……):
    在这里插入图片描述
    直到C++20版本才引入。

    二、类模板的特化

    模板的特化就是针对某些类型进行特殊化处理。
    比如我们现在随便写一个类模板:
    在这里插入图片描述
    如果我们想针对两个参数一个是int一个是double的这种情况特殊处理,让它输出不同的内容就可以使用特化:
    在这里插入图片描述
    上面的这种叫做全特化,与之对应的还有偏特化:
    在这里插入图片描述
    在匹配的时候也是遵循最匹配原则,看哪个最符合条件就匹配哪个。

    而且在特化的时候也并不需要写的很具体,其实也可以像下面这样写:
    在这里插入图片描述

    特化必须要有原模板,也就是最初的没有任何特化的模板。

    三、模板的分离编译

    模板其实是不支持分离编译的,即声明和定义分离(声明在一个文件,定义在另个文件)。
    在这里插入图片描述
    在这里插入图片描述
    这样做的话会发生连接错误:
    在这里插入图片描述

    而我们若是讲一个普通函数分离编译就没问题:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    这其中的原因是因为函数模板比普通函数多了一个步骤:实例化,因为函数模板其实和具体函数其实是一个一对多的关系,一个函数模板可以实例化出很多个功能相近但参数和返回值类型不同的函数。
    也就是说我们在Stack.cpp中所写的可以比作一个骨架,从中只能得到这个函数的实现逻辑,所以在编译Stack.cpp的时候并不能生成具体的函数地址,这样main函数在调用的时候就自然找不到了。

    解决这个问题的其中一种方法就是显示实例化:
    在这里插入图片描述
    在这里插入图片描述

    但这种方法并不是一种很好的方法,因为它每一次只能解决一种类型,而且每一种类型都得要显示声明一次,这会是代码用于。

    还有一种方法就是直接将声明和定义放在同一个文件里:
    在这里插入图片描述

  • 相关阅读:
    vue中原生H5拖拽排序_拖拽图片也是同样的道理
    java计算机毕业设计ssm二手商品交易平台
    33个非常实用的JavaScript一行代码,建议收藏!
    Java设计模式之代理模式(一)
    【毕业设计】22-基于单片机的智能温度计的系统设计(原理图工程+仿真工程+源代码+仿真视频+答辩论文+答辩PPT)
    网络是怎样连接的--TCP大致控制流程
    [LeetCode]剑指 Offer 40. 最小的k个数
    子类继承了什么、多态、 向上转型
    Junit5的断言方式,一学就会
    3.17 让你的小红书笔记排名更靠前的六个方法【玩赚小红书】
  • 原文地址:https://blog.csdn.net/kk702392702/article/details/133924266