模版进阶篇章

devtools/2024/11/15 4:13:37/

非类型模版参数

回顾:函数模版 :不用传类型,编译器会自动推导,和普通的函数调用一样

#include<iostream>
using namespace std;
template<typename T>// T是类型
bool Less(T a, T b)// a,b是T实例化的的对象
{return a < b;
}
int main()
{cout << Less<int>(1,2) << endl;cout << Less(1, 2) << endl;return 0;
}

类模版:通过传不同的类型,编译器会自动生成不同的类,然后进行实例化对象

namespace bit
{template<typename T>// T是类型class array{array( int size = 1 ){_array = new T[size];_size = size;}bool empty(){return _size == 0;}int size(){return _size;}private:T* _array;int _size;};
}

注意:调用函数模版时,需要传对象(匿名实例化 或者 有名实例化)         

           调用类模版时,需要传类型

#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
int main()
{
//函数模版vector<int> s = { 1, 2, 4, 6, 7,3,1 };sort(s.begin(), s.end(), less<int>());//升序for (auto& e : s)cout << e << " ";cout << endl;sort(s.begin(), s.end(), greater<int>());//降序for (auto& e : s)cout << e << " ";cout << endl;
//类模版priority_queue<int, vector<int>, less<int>> k;// 传的是类型k.push(1);k.push(3);k.push(9);k.push(10);while (!k.empty()){cout << k.top() << " ";k.pop();}cout << endl;return 0;
}

非类型模版参数

概念:将常量作为模版参数

注意:1.只有整形家族才能支持非类型模版参数

           2.参数在编译时就能确定

#include<iostream>
#include<algorithm>
using namespace std;
namespace bit
{template<typename T ,size_t size = 10>class array//静态数组{public:array( ){_array = new T[size];_size = size;}bool empty(){return _size == 0;}int size(){return _size;}private:T* _array;int _size;};
}
int main()
{bit::array<int, 20> s;return 0;
}

模版参数可以支持缺省参数(类似于函数)

在priority_queue中我们以vector作为priority_queue的底层(参考我的另一篇文章:详细的讲解priority_queuede的用法与底层https://blog.csdn.net/wx20041102/article/details/138355281?spm=1001.2014.3001.5501)

模版特化

通常情况下,使用模板可以实现一些与类型无关的代码,但对于一些特殊类型的可能会得到一些错

误的结果

列如:

#include<iostream>
#include<deque>
#include<algorithm>
#include<vector>template<typename T>
class Less
{
public:bool operator() (const T& x, const T& y){return x < y;}
};template<typename T>
class Greater
{
public:bool operator() (const T& x, const T& y){return y < x;}
};class Date
{
public:Date(int year, int month, int day): _year(year), _month(month), _day(day){}bool operator<(const Date& s){if (s._year > _year)return true;else if (s._year == _year){if (s._month > _month)return true;else if (s._month == _month){if (s._day > _day)return true;}}return false;}
private:int _year;int _month;int _day;
};
int main()
{Date* p1 = new Date(2024, 1, 1);Date* p2 = new Date(2024, 1, 4);Less<Date*> ls;cout << ls(p1 , p2) << endl;//这里比较的是地址大小,而我们想要比较指向的内容大小return 0;
}

解决方案:特化

  • 函数模版特化

步骤如下:

1.必须要有一个基础的函数模版

2.关键字template后接一对空的<>

3.直接在()中写出要特化的类型

4.函数形参表:必须要和模版参数的基础类型完全相同

#include<iostream>
#include<vector>
using namespace std;template<typename T>
bool Less(T& x, T& y)
{return x < y;
}template<typename T>
bool Less(int*& x, int*& y)
{return *x < *y;
}template<typename T>
bool Less(string*& x, string*& y)
{return *x < *y;
}
int main()
{int* p1 = new int(1);int* p2 = new int(3);cout << Less<int*>(p1, p2) << endl;return 0;
}

既然参数类型已经确定,那么函数模版也可以用函数重载(这是我们经常用的)

#include<iostream>
#include<vector>
using namespace std;template<typename T>
bool Less(T& x, T& y)
{return x < y;
}bool Less(int*& x, int*& y)
{return *x < *y;
}bool Less(string*& x, string*& y)
{return *x < *y;
}
int main()
{int* p1 = new int(1);int* p2 = new int(3);cout << Less<int*>(p1, p2) << endl;return 0;
}
  • 类模版特化

  • 全特化

类型全部确定

步骤如下:

1.template 后接一对<>

2.class 类型名 + < 类型 >//注意这里要将类模版中全部的参数写出来

#include<iostream>
#include<algorithm>
using namespace std;
template<typename T , typename K>
class date
{
public:date(){cout << "111111111" << endl;}
private:T _a;K _b;
};
template<>
class date<int,char>
{
public:date(){cout << "22222222222" << endl;}
private:int _a;char _b;
};int main()
{date<int, char> s;date<char, char> k;date<int, int> q;
}
  • 偏特化
部分特化

1.template< 需要实例化的类型 >//template<typename T>

2.class <需要实例化的类型 + 缺省类型 >// class < T , char >

#include<iostream>
#include<algorithm>
using namespace std;
template<typename T , typename K>
class date
{
public:date(){cout << "111111111" << endl;}
private:T _a;K _b;
};
template<>
class date<int,char>
{
public:date(){cout << "22222222222" << endl;}
private:int _a;char _b;
};
template<typename T >
class date< T , char >
{
public:date(){cout << "3333333333" << endl;}
private:T _a;char _b;
};
int main()
{date<int, char> s;date<char, char> k;date<int, int> q;
}
限制特化

以某个性质限制,列如指针 ,引用

#include<iostream>
#include<deque>
#include<algorithm>
#include<vector>template<typename T>
class Less
{
public:bool operator() (const T& x, const T& y){return x < y;}
};
template<typename T>
class Less<T*>// 限制特化 只有指针才能进入这里
{
public:bool operator()( T* x, T* y){return *x < *y;}
};template<typename T>
class Less<T&>// 限制特化 只有引用才能进入这里
{
public:bool operator()( T& x, T& y){return x < y;}
};template<typename T>
class Greater
{
public:bool operator() (const T& x, const T& y){return y < x;}
};class Date
{
public:Date(int year, int month, int day): _year(year), _month(month), _day(day){}bool operator<(const Date& s){if (s._year > _year)return true;else if (s._year == _year){if (s._month > _month)return true;else if (s._month == _month){if (s._day > _day)return true;}}return false;}
private:int _year;int _month;int _day;
};
int main()
{Date* p1 = new Date(2024, 1, 1);Date* p2 = new Date(2024, 1, 4);Less<Date*> ls;cout << ls(p1 , p2) << endl;return 0;
}


http://www.ppmy.cn/devtools/31593.html

相关文章

ResponseHttp

文章目录 HTTP响应详解使用抓包查看响应报文协议内容 Response对象Response继承体系Response设置响应数据功能介绍Response请求重定向概述实现方式重定向特点 请求重定向和请求转发比较路径问题Response响应字符数据步骤实现 Response响应字节数据步骤实现 HTTP响应详解 使用抓…

node.js中path模块-路径处理,语法讲解

node中的path 模块是node.js的基础语法&#xff0c;实际开发中&#xff0c;我们通过使用 path 模块来得到绝对路径&#xff0c;避免因为相对路径带来的找不到资源的问题。 具体来说&#xff1a;Node.js 执行 JS 代码时&#xff0c;代码中的路径都是以终端所在文件夹出发查找相…

C语言 | Leetcode C语言题解之第62题不同路径

题目&#xff1a; 题解&#xff1a; int uniquePaths(int m, int n) {long long ans 1;for (int x n, y 1; y < m; x, y) {ans ans * x / y;}return ans; }

生成对抗网络(GAN)入门

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f366; 参考文章&#xff1a;TensorFlow入门实战&#xff5c;第3周&#xff1a;天气识别&#x1f356; 原作者&#xff1a;K同学啊|接辅导、项目定制 一、理论基础 1.什么是GAN GAN&#xff08…

发卡授权盗u系统源码ZHU

2024最新UI发卡盗U/支持多语言/更新UI界面/支持多个主流钱包去除后门板&#xff0c; 搭建系统TGaqxm01&#xff0c;最好是部署智能合约后用合约地址来授权包含转账支付页面盗U授权源码。 完美提U&#xff0c;教程包含如何提u 。功能完美。 1.Php静态 2.目录puicta 3.扩sal 4.s…

Django框架之请求生命周期流程图

一、引言 WSGI、wsgiref、uwsgi三者是什么关系? WSGI是协议&#xff0c;小写的wsgiref和uwsgi是实现该协议的功能模块 缓存数据库 提前已经将你想要的数据准备好了&#xff0c;需要的时候直接拿就可以&#xff0c;提高了效率和响应时间。 eg:当你在修改你的数据的时候&…

搭建和配置Stable Diffusion环境,超详细的本地部署教程

跃然纸上的创意、瞬息万变的想象&#xff0c;Stable Diffusion以AI的力量赋予您无限创作可能。在这篇详尽的本地部署教程中&#xff0c;我们将携手走进Stable Diffusion的世界&#xff0c;从零开始&#xff0c;一步步搭建和配置这个强大的深度学习环境。无论您是热衷于探索AI艺…

搭建MongoDB副本集

文章目录 一、什么是MongoDB的副本集二、副本集的架构三、副本集的成员四、部署副本集1、节点划分2、安装MongoDB2.1、下载解压安装包 3、创建主节点3.1、创建存储数据和日志的目录3.2、新建配置文件3.3、启动节点服务 4、创建副本节点4.1、创建存储数据和日志的目录4.2、新建配…