C++ 模板进阶

2024-02-26 1631阅读

温馨提示:这篇文章已超过406天没有更新,请注意相关的内容是否还可用!

C++ 模板进阶

  • 一.非类型模板参数
    • 1.概念
    • 2.实例
    • 3.注意事项
    • 二.模板的特化
      • 1.引出
      • 2.函数模板的特化
        • 1.语法和使用
        • 2.建议
        • 3.类模板的特化
          • 1.全特化
          • 2.偏特化
            • 1.部分特化
            • 2.对参数进行进一步的限制
            • 4.匹配顺序
            • 三.模板的分离编译
              • 1.什么是分离编译
              • 2.模板的分离编译
              • 3.解决方法
                • 1.显式实例化(不推荐)
                • 2.分离编译放在头文件当中
                • 四.模板的总结

                  一.非类型模板参数

                  1.概念

                  模板参数分为: 类型形参与非类型形参

                  类型形参即:出现在模板参数列表中,跟在class或者typename之类的参数类型名称后面

                  非类型形参,就是用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当成常量来使用

                  2.实例

                  比方说我想实现一个静态的栈,栈的大小是10

                  #define N 10
                  template
                  class Stack
                  {
                  private:
                  	T _arr[N];
                  };
                  int main()
                  {
                  	Stack st1;
                  	Stack st2;
                  	return 0;
                  }
                  

                  C++ 模板进阶

                  可是我需求变了,st1我想要10个大小,st2我想要200个大小,st3我想要1000个大小,st4我想要2个大小…

                  怎么办?

                  此时就需要用到非类型模板参数了

                  template
                  class Stack
                  {
                  private:
                  	T _arr[N];
                  };
                  int main()
                  {
                  	Stack st1;
                  	Stack st2;
                  	Stack st3;
                  	Stack st4;
                  	return 0;
                  }
                  

                  C++ 模板进阶

                  此时你st1想要10个大小,st2想要100个大小,st3想要1000个…

                  都可以,完美的解决了这个问题

                  3.注意事项

                  1. 浮点数、类对象以及字符串是不允许作为非类型模板参数的
                  2. 非类型的模板参数必须在编译期就能确认结果

                    (因为模板是在编译阶段就要实例化的,而模板必须要知道实例化成的具体类型之后才能实例化,

                    因此非类型模板参数和类型模板参数一样,必须在编译阶段就能够确认实例化成的具体类型才可以,

                    否则编译阶段无法完成实例化,链接阶段就找不到实例化出的具体的类,进而发生链接错误)

                  二.模板的特化

                  1.引出

                  通常情况下,使用模板可以实现一些与类型无关的代码,但对于一些特殊类型的可能会得到一些错误的结果,需要特殊处理,比如:实现了一个专门用来进行小于比较的函数模板

                  我们写一个非常简易的日期类,用这个日期类开始下面的介绍

                  这里给出了头文件,至于源文件就不给大家了,毕竟我们这篇博客的目的也不是实现日期类

                  关于日期类的完善大家可以看我的这篇博客:

                  C++类和对象中:运算符重载+const成员函数+日期类的完善

                  C++ 模板进阶

                  C++ 模板进阶

                  对于第三个比较,我们想要比较的其实是p1和p2,可是实际比较的是p1和p2这两个指针

                  不符合我们的期望,怎么办呢?

                  2.函数模板的特化

                  1.语法和使用

                  C++ 模板进阶

                  因此我们就可以这样特化

                  // 函数模板 -- 参数匹配
                  //基础的函数模板
                  template
                  bool Less(T left, T right)
                  {
                  	return left  
                  

                  C++ 模板进阶

                  特化之后,如果函数模板的参数跟特化的类型是匹配的,那么就会走特化,并不会走函数的基础模板

                  跟我们之前学的函数模板推演实例化时如果有更匹配的会优先去匹配那个更匹配的,这个原则是一样的

                  2.建议

                  不建议大家使用函数模板的特化,而建议大家直接写一个同名的非函数模板即可,

                  因为:

                  1.函数模板的特化和直接写一个同名的非模板函数的工作量是一样的

                  2.函数模板的特化的要求更多

                  比如:必须要有一个基础的函数模板

                  而且函数形参表: 必须要和模板函数的基础参数类型完全相同

                  3.而且因为const,引用和指针的关系,导致函数模板的特化变得更加复杂

                  4.直接写一个同名的非函数模板:简单明了,代码的可读性高,容易书写

                  C++ 模板进阶

                  3.类模板的特化

                  1.全特化

                  全特化: 将模板参数列表中所有的参数都确定化

                  语法跟函数模板的特化非常相似

                  都是需要一个基础模板等等…

                  template
                  class C
                  {
                  public:
                  	C()
                  	{
                  		cout 
                  public:
                  	C()
                  	{
                  		cout 
                  public:
                  	C()
                  	{
                  		cout 
                  public:
                  	C()
                  	{
                  		cout 
                  public:
                  	C()
                  	{
                  		cout 
                  	C
                  public:
                  	bool less(const T& a, const T& b)
                  	{
                  		return a 
VPS购买请点击我

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

目录[+]