C++ 泛型编程(五) 模版重载与特例化
前文回顾:
C++ 泛型编程(一) 基本概念
C++ 泛型编程(二) 函数模版
C++ 泛型编程(三) 模版实参推断
C++ 泛型编程(四) 类模板
模版重载
函数模版可以被另一个模版或者一个普通非模版函数重做;名字相同的函数必须具有不同数量或者类型的参数。
- 根据参数推断只有一个版本是可行的,则选择该版本
- 都是可行的,匹配更精确的版本
- 都是精确匹配,选择特化版本
- 普通函数可以匹配,选择普通函数
- 通过空模板实参列表限定只匹配模板
模版特例化
概念
①.特例化:模板,代表了一种泛化的语义,与之相对的就是特化语义。特例化,使得我们能为某些特定的类型专门提供一份特殊实现;特例化本质上是我们顶替了编译器的工作,我们帮编译器做了类型推导。
②.全特化:本质上是一个实例,我们必须为模版中每个参数都提供实参。使用关键字 template 加空尖括号对 <> 定义。
③.偏特化:本质上还是一个模板,只是原来模板的一个子集。
函数模版特例化
①.定义
函数模版的不存在偏特化,偏特化即为模版的重载。
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; }
②.头文件
模版及其特例化版本应该声明在同一个头文件中,所有同名模版的声明应该放在特例化版本之前。
类模版特例化
①.类模版全特化
跟函数模板一样,全特化是一个实例,当编译器匹配时会优先匹配参数一致的实例。
//类模版 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> 的一个成员 {}
可变参数模版
概念
①.可变参数模版:就是可以接受可变数据参数的模版函数和模版类,即参数数量、以及每个参数的类型都未知且各不相同。
②.参数包:可变数目的参数称为参数包,用省略号来表示一个包。
③.模版参数包:表示零个或者多个模版参数,用 typename… 声明。
④.函数参数包:表示零个或者多个函数参数。
⑤.sizeof…:获取参数包内参数的数量
⑥:Pattern…:以某一模式展开参数包,用省略好触发扩展操作。
定义可变参数模版
可变参数模版通常是递归的,参数包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() {}
转发参数包
可变参数函数也可以将它的参数转发给其他函数。模版参数包扩展为一个右值引用的列表,函数参数扩展为一个用 forward 保持类型不变的一个列表。
template<typename... Args> //模版参数扩展模式:Args&&,扩展为右值引用列表 void fun(Args&&... rest) {//函数参数扩展模式:forward<Args>(rest),对每个参数取相同操作work(std::forward<Args>(rest)...); }
C++ 泛型编程(五) 模版重载与特例化相关推荐
- C++ Primer 5th笔记(chap 16 模板和泛型编程)类模板部分特例化
1. 类模板的部分特例化(partial specialization) 类模板的特例化不必为所有模板参数提供实参(可以只指定一部分而非所有模板参数, 或是参数的一部分而非全部特性).类模板的部分特例 ...
- C++ Primer 5th笔记(chap 16 模板和泛型编程)模板特例化
1. 场景 //第一个版本:可以比较任意两个类型 template <typename T> int compare (const T &, const T & );//第 ...
- C++模板与泛型编程:模板特例化
文章目录 模板特例化 定义函数模板特例化 函数重载与模板特例化 类模板特例化 类模板部分特例化 特例化成员而不是类 模板特例化 编写单一模板,使之对任何可能的模板实参都是最合适的,都能实例化,这并 ...
- C++ Primer 5th笔记(chap 16 模板和泛型编程)类模板特例化
1. 定义一个特例化版本, 模板参数为 Sales data // 打开std 命名空间, 以便特例化 std::hash namespace std {template struct hash< ...
- 类和函数模板以及特例化
一.函数模板 1.定义 建立一个通用函数,它所用到的数据的类型(包括返回值类型.形参类型.局部变量类型)可以不具体指定,而是用一个虚拟的类型来代替(实际上是用一个标识符来占位),等发生函数调用时再根据 ...
- C++模板的特例化编译为多重定义问题
之前遇到了一些关于模板特例化的问题,自己总结一下. 模板的特例化是C++新标准的一个特点,可以自定义某些模板的实现,比如在比较函数compare可以使用less<T>标准库模板比较stri ...
- C++:19---重载与模板、模板特例化
一.重载与模板 函数模板可以被另一个模板或一个普通非模板函数重载 如果涉及函数模板,则函数匹配规则会有以下的约束: 如果同样好的函数中只有一个是非模板函数,则选择此函数 如果同样好的函数中没有非模板函 ...
- c++primer第十六章模板特例化
16.5模板特例化 //第一个版本,可以比较任意两个类型 template<typename T> int compare(const T&p1, const T&p2) ...
- 【深入理解C++】函数模板和类模板的特例化
文章目录 1.函数模板的特例化 1.1 函数模板的全特化 1.2 函数模板不能偏特化 1.3 函数模板.函数模板的全特化.普通函数 2.类模板的特例化 2.1 类模板的全特化 2.2 类模板成员函数的 ...
最新文章
- 【spring】spel表达式
- 3.3V稳压IC芯片 1117-3.3V性能测试
- 查看php-fpm 占用内存情况
- 缓存雪崩,缓存穿透,缓存预热,缓存热备都是什么鬼?
- elementui中同时上传多个文件_element ui 上传文件,批量一次上传多个文件,为什么是发送了多次请求,我想一次请求,然后发送多个文件怎么实现呢?...
- 001redis数据库的介绍
- ubuntu 串口调试工具推荐_串口调试能有多便捷?——FUR组件的应用
- 李雅普诺夫和MIT两个MRAC案例的xcos模型
- unity 加载完场景继续加载场景中的物体_Unity光照渲染原理
- python在线题库推荐_Python题库.docx
- EXCEL:两列数据的重复和非重复值(顺序打乱)
- 移动设备管理与OMA DM 协议 V5(3)
- 13款入侵检测系统介绍(HIDS)
- 讯飞离线语音合成(语记)
- 计算机校本研究题目,信息技术小课题研究题目大全
- 勤于奋:国外LEAD账号申请细节
- 万字长文:编写 Dockerfiles 最佳实践
- 字体图标兼容性,兼容IE
- java Word 转 PDF格式
- Pjsip笔记之pjsip使用示例