前文回顾:
C++ 泛型编程(一) 基本概念
C++ 泛型编程(二) 函数模版
C++ 泛型编程(三) 模版实参推断
C++ 泛型编程(四) 类模板

模版重载

函数模版可以被另一个模版或者一个普通非模版函数重做;名字相同的函数必须具有不同数量或者类型的参数。

  1. 根据参数推断只有一个版本是可行的,则选择该版本

  1. 都是可行的,匹配更精确的版本

  1. 都是精确匹配,选择特化版本

  1. 普通函数可以匹配,选择普通函数

  1. 通过空模板实参列表限定只匹配模板

模版特例化

  1. 概念

    ①.特例化:模板,代表了一种泛化的语义,与之相对的就是特化语义。特例化,使得我们能为某些特定的类型专门提供一份特殊实现;特例化本质上是我们顶替了编译器的工作,我们帮编译器做了类型推导。

    ②.全特化:本质上是一个实例,我们必须为模版中每个参数都提供实参。使用关键字 template 加空尖括号对 <> 定义。

    ③.偏特化:本质上还是一个模板,只是原来模板的一个子集。

  2. 函数模版特例化

    ①.定义

    函数模版的不存在偏特化,偏特化即为模版的重载。

    template<class T>
    T add(T a, T b) { return a + b;}
    //特例化版本,template<>
    template< >
    double add(double a, double b)  { return a + b; }
    //重载版本,还是模版
    template<class T1>  
    T1 add(T1* a, T1* b) { return *a + *b; }
    

    ②.头文件

    模版及其特例化版本应该声明在同一个头文件中,所有同名模版的声明应该放在特例化版本之前。

  3. 类模版特例化

    ①.类模版全特化

    跟函数模板一样,全特化是一个实例,当编译器匹配时会优先匹配参数一致的实例。

    //类模版
    template<class T>
    class A
    {
    public:explicit A(T val) : t(val) { }T add(T x) { return t + x; }
    privete:T t;
    };
    //全特化
    template< >
    class A<char*>  // 一个全特化的模板类A
    {
    public:explicit A(char* val) : t(val) { }char* add(char* x) { return strcat(t, x); }
    private:char* t;
    };
    

    ②.偏特化-指定部分参数

    template<class T1, class T2>      // 普通版本,有两个模板参数
    class B { ..... };template<class T2>            // 偏特化版本,指定其中一个参数,即指定了部分类型
    class B<int , T2> { ..... };  
    

    ③.偏特化-指定参数形式

    template<class T>     // 普通版本
    class B { ..... };template<class T>   //这个偏特化版本只接收指针类型的模板实参
    class B<T*> { ..... };
    

    ③.特例化成员

    我们也可以只特例化特定成员函数而不是特例化整个模版。

    //类模版
    template <typename T>
    class FOO
    {
    public:FOO(const T &t = T()):mem(t){}void Bar(){}
    private:T mem;
    }
    template<>//全特化
    void FOO<int>::Bar()//特例化 FOO<int> 的一个成员
    {}
    

可变参数模版

  1. 概念

    ①.可变参数模版:就是可以接受可变数据参数的模版函数和模版类,即参数数量、以及每个参数的类型都未知且各不相同。

    ②.参数包:可变数目的参数称为参数包,用省略号来表示一个包。

    ③.模版参数包:表示零个或者多个模版参数,用 typename… 声明。

    ④.函数参数包:表示零个或者多个函数参数。

    ⑤.sizeof…:获取参数包内参数的数量

    ⑥:Pattern…:以某一模式展开参数包,用省略好触发扩展操作。

  2. 定义可变参数模版

    可变参数模版通常是递归的,参数包Args …在展开的过程中递归调用自己,没调用一次参数包中的参数就会少一个, 直到所有参数都展开为止。

    //Args 是一个模版参数包,表示零个或者多个模版类型的参数
    //rest 是一个函数参数包,表示零个或者多个函数参数
    template<typename T, typename... Args>
    //函数每次分解出一个 val,剩下的再构成一个包
    //模版参数扩展模式:const Args &,对包中每个参数取相同的操作
    //等价于:void print(const T &val, const T1 &t1,const T2 &t2,const T3 &3,const T4 &t4,...)
    void print(const T &val, const Args &... rest)
    {//每次打印一个参数cout << val << endl;//递归继续分解//函数参数扩展模式:rest//等价于print(rest1,rest2,rest3,rest4,...)print(rest...);
    }
    //递归终点
    void print() {}
  3. 转发参数包

    可变参数函数也可以将它的参数转发给其他函数。模版参数包扩展为一个右值引用的列表,函数参数扩展为一个用 forward 保持类型不变的一个列表。

    template<typename... Args>
    //模版参数扩展模式:Args&&,扩展为右值引用列表
    void fun(Args&&... rest)
    {//函数参数扩展模式:forward<Args>(rest),对每个参数取相同操作work(std::forward<Args>(rest)...);
    }
    

C++ 泛型编程(五) 模版重载与特例化相关推荐

  1. C++ Primer 5th笔记(chap 16 模板和泛型编程)类模板部分特例化

    1. 类模板的部分特例化(partial specialization) 类模板的特例化不必为所有模板参数提供实参(可以只指定一部分而非所有模板参数, 或是参数的一部分而非全部特性).类模板的部分特例 ...

  2. C++ Primer 5th笔记(chap 16 模板和泛型编程)模板特例化

    1. 场景 //第一个版本:可以比较任意两个类型 template <typename T> int compare (const T &, const T & );//第 ...

  3. C++模板与泛型编程:模板特例化

    文章目录 模板特例化 定义函数模板特例化 函数重载与模板特例化 类模板特例化 类模板部分特例化 特例化成员而不是类 模板特例化 ​ 编写单一模板,使之对任何可能的模板实参都是最合适的,都能实例化,这并 ...

  4. C++ Primer 5th笔记(chap 16 模板和泛型编程)类模板特例化

    1. 定义一个特例化版本, 模板参数为 Sales data // 打开std 命名空间, 以便特例化 std::hash namespace std {template struct hash< ...

  5. 类和函数模板以及特例化

    一.函数模板 1.定义 建立一个通用函数,它所用到的数据的类型(包括返回值类型.形参类型.局部变量类型)可以不具体指定,而是用一个虚拟的类型来代替(实际上是用一个标识符来占位),等发生函数调用时再根据 ...

  6. C++模板的特例化编译为多重定义问题

    之前遇到了一些关于模板特例化的问题,自己总结一下. 模板的特例化是C++新标准的一个特点,可以自定义某些模板的实现,比如在比较函数compare可以使用less<T>标准库模板比较stri ...

  7. C++:19---重载与模板、模板特例化

    一.重载与模板 函数模板可以被另一个模板或一个普通非模板函数重载 如果涉及函数模板,则函数匹配规则会有以下的约束: 如果同样好的函数中只有一个是非模板函数,则选择此函数 如果同样好的函数中没有非模板函 ...

  8. c++primer第十六章模板特例化

    16.5模板特例化 //第一个版本,可以比较任意两个类型 template<typename T> int compare(const T&p1, const T&p2) ...

  9. 【深入理解C++】函数模板和类模板的特例化

    文章目录 1.函数模板的特例化 1.1 函数模板的全特化 1.2 函数模板不能偏特化 1.3 函数模板.函数模板的全特化.普通函数 2.类模板的特例化 2.1 类模板的全特化 2.2 类模板成员函数的 ...

最新文章

  1. 【spring】spel表达式
  2. 3.3V稳压IC芯片 1117-3.3V性能测试
  3. 查看php-fpm 占用内存情况
  4. 缓存雪崩,缓存穿透,缓存预热,缓存热备都是什么鬼?
  5. elementui中同时上传多个文件_element ui 上传文件,批量一次上传多个文件,为什么是发送了多次请求,我想一次请求,然后发送多个文件怎么实现呢?...
  6. 001redis数据库的介绍
  7. ubuntu 串口调试工具推荐_串口调试能有多便捷?——FUR组件的应用
  8. 李雅普诺夫和MIT两个MRAC案例的xcos模型
  9. unity 加载完场景继续加载场景中的物体_Unity光照渲染原理
  10. python在线题库推荐_Python题库.docx
  11. EXCEL:两列数据的重复和非重复值(顺序打乱)
  12. 移动设备管理与OMA DM 协议 V5(3)
  13. 13款入侵检测系统介绍(HIDS)
  14. 讯飞离线语音合成(语记)
  15. 计算机校本研究题目,信息技术小课题研究题目大全
  16. 勤于奋:国外LEAD账号申请细节
  17. 万字长文:编写 Dockerfiles 最佳实践
  18. 字体图标兼容性,兼容IE
  19. java Word 转 PDF格式
  20. Pjsip笔记之pjsip使用示例

热门文章

  1. 使用PowerShell 获取AAD 用户的license授予时间
  2. golang_iota
  3. “代理服务器出现问题,或者地址有误”解决方案
  4. matlab中希腊字母相除,如何在matlab中输入希腊字母
  5. 常见元素 – p元素
  6. 软考准备之系统开发与运行(错题及重要知识点)
  7. arr.map()的使用
  8. 大学四年,因为这些网站,他顺利拿下字节跳动的offer!
  9. Android 生成随机颜色值
  10. 解读 ESP32 API参考-system-App Image Format