当前位置: 首页 > news >正文

C++ 模板特化

非类型模板参数

定义:对于函数模板和类模板,模板参数并不局限于类型,普通值也可以作为模板参数

非类型模板参数定义的是常量

template<typename T, size_t N>
class array;
//T:类型模板参数
//N:非类型模板参数,一个常量

使用场景:

template<typename T, size_t N>
class Stack{
private:T _arr[N];int _top;
};int main(){Stack<int,100> st1;Stack<float,500> st2;return 0;
}

注意:

  1. 非类型模板参数是常量,不能修改
template<typename T, size_t N>
class Stack{
public:void f(){N=10; //不可修改非类型模板参数}
private:T _arr[N];int _top;
};int main(){Stack<int,100> st1;st1.f();return 0;
}
  1. 有些类型不能作为非类型模板参数,例如浮点数、类对象、字符串,非类型模板参数基本上都是整型,也只有整型是有意义和价值的【char 是整型】
  2. 非类型模板参数必须在编译期就能确认结果

array

#include<iostream>
#include<array>
#include<vector>
using namespace std;
int main() {vector<int> v1(100, 0);array<int, 100> a1;cout << "size of v1:" << sizeof(v1) << endl;cout << "size of a1:" << sizeof(a1) << endl;return 0;
}

vector 在堆上开辟空间,array 在栈上开辟空间

用 array 对标 vector 是错误的,与原生数组可以对比

array<int, 100> a1;
int a2[100];

array 的最大优势:有一个越界的检查,读和写都可以检查到是否越界

总结:array 相较于原生数组,有越界检查的优势,实际中建议直接使用 vector

模板特化

引入:给特殊类型准备特殊模板。使用模板可以实现一些与类型无关的代码,对于一些特殊类型,对其进行一些“特殊的处理”

定义:针对某些类型进行特殊化处理

函数模板的特化

步骤:

  1. 必须先有一个基础的函数模板
  2. 关键字 template 后面接一对空的 <>
  3. 函数名后跟一对尖括号,尖括号中指定需要特化的内容
  4. 函数形参表必须和模板函数的基础参数类型完全相同

PS:函数模板不一定非要特化,写一个匹配参数的普通函数更容易理解

#include<iostream>
#include "Date.h"
using namespace std;
//函数模板
template<typename T>
bool Less(T left, T right){return left < right;
}
//函数模板的特化处理
template<>
bool Less<Date*>(Date* left, Date* right){return *left < *right;
}
//直接匹配的普通函数
bool Less(Date* left, Date* right){return *left < right;   
}
int main(){cout << Less(1, 2) << endl;Date d1(2022, 7, 7);Date d2(2022, 7, 8);cout << Less(d1, d2) << endl;Date* p1 = new Date(2022, 7, 16);Date* p2 = new Date(2022, 7, 15);cout << Less(p1, p2) << endl;//若存在直接匹配的普通函数(函数重载),会优先使用现成的函数重载,不用实例化return 0;
}

类模板的特化

类模板无法实现一个具体的实际类型,故必须特化

#include<iostream>
using namespace std;
template<typename T1, typename T2>
//类模板
class Data {
public:Data() {cout << "Data <T1, T2>" << endl;}
private:T1 _d1;T2 _d2;
};
//类模板的特化
template<>
class Data<int, double> {
public:Data() {cout << "Data <int, double>" << endl;}
};
int main(void) {Data<int, int> d1;Data<int, double> d2;return 0;
}

全特化

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

#include<iostream>
using namespace std;
//类模板
template<typename T1, typename T2>
class Data {
public:Data() {cout << "Data <T1, T2>" << endl;}
private:T1 _d1;T2 _d2;
};
//全特化
template<>
class Data<int, double> {
public:Data() {cout << "Data <int, double>" << endl;}
};
int main(void) {Data<int, int> d1;Data<int, double> d2;return 0;
}

半特化 / 偏特化

定义:将部分参数类表中的一部分参数特化

#include<iostream>
using namespace std;
//类模板
template<typename T1, typename T2>
class Data {
public:Data() {cout << "Data <T1, T2>" << endl;}
private:T1 _d1;T2 _d2;
};
//半特化
template<typename T1>
class Data<T1, char> {
public:Data() {cout << "Data <T1, char>" << endl;}
};
//半特化的另一种表现形式,可以对参数进行进一步限制
//限制两个参数都是指针:只要两个参数都是指针,就匹配
template<typename T1, typename T2>
class Data<T1*, T2*> {
public:Data() {cout << "Data <T1*, T2*>" << endl;}
};
//限制两个参数都是引用:只要两个参数都是引用,就匹配
template<typename T1, typename T2>
class Data<T1&, T2&> {
public:Data() {cout << "Data <T1&, T2&>" << endl;}
};
int main(void) {Data<int, char> d3;       // Data <T1, char>Data<char, char> d4;      // Data <T1, char>Data<int*, char*> d5;     // Data <T1*, T2*>Data<char*, string*> d6;  // Data <T1*, T2*>Data<char**, void*> d7;   // Data <T1*, T2*>Data<int, char*> d8;      // Data <T1, T2>Data<int&, char&> d9;     // Data <T1&, T2&>Data<char&, string&> d10;  // Data <T1&, T2&>Data<int, char&> d11;      // 编译错误return 0;
}

http://www.lryc.cn/news/217447.html

相关文章:

  • Spring-createBean部分源码
  • 2015年亚太杯APMCM数学建模大赛C题识别网络中的错误连接求解全过程文档及程序
  • js:可选链运算符(?.)和空值合并运算符(??)
  • 【Java 进阶篇】Java ServletContext功能:获取文件服务器路径
  • Android startActivity流程
  • Qt实验室
  • diffusers-Load adapters
  • CVI 串口调试助手
  • 【蓝桥杯选拔赛真题48】python最小矩阵 青少年组蓝桥杯python 选拔赛STEMA比赛真题解析
  • 如何在家庭网络中开启 IPv6内网穿透
  • CodeWhisperer 的安装及体验
  • 【C/C++】虚析构和纯虚析构
  • 第四章 应用SysML基本特性集的汽车示例 P1|系统建模语言SysML实用指南学习
  • C语言 写一个简易音乐播放器
  • 面试题:有一个 List 对象集合,如何优雅地返回给前端?
  • DAY43 完全背包理论基础 + 518.零钱兑换II
  • unity 从UI上拖出3D物体,(2D转3D)
  • win10pycharm和anaconda安装和环境配置教程
  • [C++ 中]:6.类和对象下(static成员 + explicit +友元函数 + 内部类 + 编译器优化)
  • ONES Design UI 组件库环境搭建
  • 支付宝AI布局: 新产品助力小程序智能化,未来持续投入加速创新
  • taro全局配置页面路由和tabBar页面跳转
  • 【k8s】pod进阶
  • 【设计模式】第18节:行为型模式之“迭代器模式”
  • 【数据结构】单链表OJ题
  • 智能工厂架构
  • 阿里云多款ECS产品全面升级 性能最多提升40%
  • 责任链模式(Chain of Responsibility)
  • 文件管理技巧:根据大小智能分类并移动至目标文件夹
  • 具有自主产权的SaaS门店收银系统全套源码输出