码农知识堂 - 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.出现模板编译错误时,错误信息非常凌乱,不易定位错误


  • 相关阅读:
    数据结构初阶leetcodeOJ题(二)
    Go微服务实战 - 用户服务开发(gRPC+Protocol Buffer)
    查看项目go代码cpu利用率
    手机搭建服务器保姆级教程,无需root
    Hive及Sqoop的表操作
    Centos 7双网卡绑定配置
    MySQL——无法打开MySQL8.0软件安装包或者安装过程中失败,如何解决?
    CTFSHOW七夕杯web
    BUUCTF:[MRCTF2020]套娃
    拥抱Jetpack之印象篇
  • 原文地址:https://blog.csdn.net/YQ20210216/article/details/126892284
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号