码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 【初阶与进阶C++详解】第十二篇:模板进阶(函数模板特化+类模板特化+模板分离编译)


    🏆个人主页:企鹅不叫的博客

    ​ 🌈专栏

    • C语言初阶和进阶
    • C项目
    • Leetcode刷题
    • 初阶数据结构与算法
    • C++初阶和进阶
    • 《深入理解计算机操作系统》
    • 《高质量C/C++编程》
    • Linux

    ⭐️ 博主码云gitee链接:代码仓库地址

    ⚡若有帮助可以【关注+点赞+收藏】,大家一起进步!

    💙系列文章💙

    【初阶与进阶C++详解】第一篇:C++入门知识必备

    【初阶与进阶C++详解】第二篇:C&&C++互相调用(创建静态库)并保护加密源文件

    【初阶与进阶C++详解】第三篇:类和对象上(类和this指针)

    【初阶与进阶C++详解】第四篇:类和对象中(类的六个默认成员函数)

    【初阶与进阶C++详解】第五篇:类和对象下(构造+static+友元+内部类

    【初阶与进阶C++详解】第六篇:C&C++内存管理(动态内存分布+内存管理+new&delete)

    【初阶与进阶C++详解】第七篇:模板初阶(泛型编程+函数模板+类模板+模板特化+模板分离编译)

    【初阶与进阶C++详解】第八篇:string类(标准库string类+string类模拟实现)

    【初阶与进阶C++详解】第九篇:vector

    【初阶与进阶C++详解】第十篇:list

    【初阶与进阶C++详解】第十一篇:stack+queue+priority_queue+deque


    文章目录

    • 💙系列文章💙
    • 💎一、非类型模板参数
    • 💎二、模板的特化
      • 🏆1.函数模板的特化
      • 🏆2.类模板的特化
        • 2.1全特化
        • 2.2偏特化
    • 💎三、模板分离编译
      • 🏆1.实例
      • 🏆2.原因
      • 🏆3.解决方法
    • 💎四、模板优缺点


    💎一、非类型模板参数

    模板参数分类类型形参与非类型形参。

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

    • 非类型模板形参:用一个常量(浮点数,字符串,类对象不允许作为非类型模板参数)(可以是 int short char long longlong)作为模板的一个参数,必须是整形家族中的类型参数。

    • template<class T =int, size_t N = 10>
      class array
      {
          private:
          T _array[N];
          size_t _size;
      }
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8

    💎二、模板的特化

    模板特化:在原模板类的基础上,针对特殊类型所进行的特殊化的实现。分为函数模板特化 和类模板特化。

    🏆1.函数模板的特化

    1. 必须先有一个基础的函数模板

    2. 关键字template后面接一对空的尖括号<>

    3. 函数名后跟一对尖括号<>,里面指定需要的特化的类型

    4. 函数形参列表:必须和函数模板的基础参数类型完全一致

      // 模板
      template<class T>
      bool IsEqual(T& left, T& right)
      {
      	return left == right;
      }
      
       // 特化
      template<>
      bool IsEqual<const char* const>(const char* const& left, const char* const& right)
      {
      	return strcmp(left, right) == 0;
      }
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14

    🏆2.类模板的特化

    2.1全特化

    对类模板参数列表的类型全部都确定

    template <class T1, class T2>
    class Date
    {
    public:
    	Date()
    	{
    		cout << "Date" << endl;
    	}
    private:
    	T1 _d1;
    	T2 _d2;
    };
    
    // 全特化
    template<>
    class Date<int, double>
    {
    public:
    	Date()
    	{
    		cout << "Date" << endl;
    	}
    private:
    	int _d1;
    	double _d2;
    };
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    2.2偏特化

    偏特化:任何针对模版参数进一步进行条件限制设计的特化版本

    偏特化有两种表现方式,一种是部分参数特化,一种是参数修饰特化

    部分特化,模板参数类表中一部分参数特化

    //第二个参数特化
    template<class T1>
    class test<T1, double>
    {
    public:
    	test()
    	{
    		cout << "test" << endl;
    	}
    
    private:
    	T1 _x;
    	double _y;
    };
    int main()
    {
    	test<double, double> t1;
    	test<int, double> t2;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    参数更进一步限制,偏特化不指是指特化部分参数,而是针对模板参数更进一步的条件限制所设计出来的一个特化版本

    //如下有T1*和T2*,是模板的类型转为指针类型和引用类型
    template<class T1, class T2>
    class test<T1*, T2*>
    {
    public:
    	test()
    	{
    		cout << "test" << endl;
    	}
    
    private:
    	T1* _x;
    	T2* _y;
    };
    
    int main()
    {
    	test<int*, double*> t;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    💎三、模板分离编译

    🏆1.实例

    **分离编译:**C++的编译器却不支持模板的分离编译,一旦进行分离编译,就会出现链接错误,下面代码就会报错。详情看这里传送门

    // a.h
    #pragma once
    
    
    // 普通函数
    void Swap(int& a, int& b);
    // 函数模板
    template<class T>
    T Add(const T& a, const T& b);
    
    // a.cpp
    #define _CRT_SECURE_NO_WARNINGS 1
    #include "a.h"
    
    // 普通函数
    void Swap(int& a, int& b)
    {
    	int tmp = a;
    	a = b;
    	b = tmp;
    }
    // 函数模板
    template<class T>
    T Add(const T& a, const T& b)
    {
    	return a + b;
    }
    
    // test.cpp
    #include "a.h"
    
    int main()
    {
    	int a = 3;
    	int b = 4;
    
    	Swap(a, b);
    	cout << "a = " << a << " b = " << b << endl;
    	cout << Add(a, b) << endl;
    	
    	return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    🏆2.原因

    1.模板在.cpp中定义了,由于不知道T的类型,所以没有对模板进行实例化。
    2.a.h 和 a.cpp 都没有对模板进行实例化,因为不知道T的类型。
    3.因为没有对模板进行实例化,所以没有函数参数,也就没有函数地址,所以在链接时,test.cpp中的调用Add函数时,没有函数地址,call调用不到Add函数,所以报错。

    🏆3.解决方法

    1. 暴力:将声明和定义统一放在一个.h或.hpp的文件中
    2. 模板定义位置显示实例化(不推荐,这样就失去了泛型的特点)

    💎四、模板优缺点

    【优点】

    ​ 1.模板复用了代码,节省资源,更快的迭代开发

    ​ 2.增强了代码的灵活性

    【缺点】

    ​ 1.导致编译时间变长

    ​ 2.出现模板编译错误时,错误信息非常凌乱,不易定位错误


  • 相关阅读:
    【横扫JDBC】JDBC 系列(老杜B站视频笔记整理)
    2021最新中高级Java面试题目,Java面试题汇总
    网络通信 mac表 tcp连接
    Springboot中的三层架构
    2024中国网络安全产品用户调查报告(发布版)
    基于Solidworks的三维光路结构示意图绘制实例演示-技术细节
    ATC:一个能将主流开源框架模型转换为昇腾模型的神奇工具
    数据库设计与建模
    AI/AO模拟量数据类型
    通用结构化剪枝DepGraph
  • 原文地址:https://blog.csdn.net/YQ20210216/article/details/126892284
  • 最新文章
  • 【JVM】编译执行与解释执行的区别是什么?JVM 使用哪种方式?
    用 Hashids 优雅解决 C 端自增 ID 暴露问题
    V8引擎 精品漫游指南--Ignition篇(上) 指令 栈帧 槽位 调用约定 内存布局 基础内容
    LLVM Pass快速入门(四):代码插桩
    milkup:桌面端 markdown AI续写和即时渲染
    基于项目工程构建SBOM(软件物料清单)的研究
    鸿蒙应用开发UI基础第二节:鸿蒙应用程序框架核心解析与实操
    .NET 中如何快速实现 List 集合去重?
    扣子Coze实战:从0到1打造抖音+小红书热点监控智能体
    浅谈数据访问层
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
小工具 小游戏
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1

京公网安备 11010502049817号