模板

1.非类型模板参数

模板参数分为类型形参与非类型形参(都可以用缺省值)

类型形参:出现在模板参数列表中,跟在class或者typename之类的参数类型名称

非类型形参:就是用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当成常量来使用

我们定义一个静态的栈

//宏#define N 10
template<class T>
class Stack
{
private:T _a[N];int _top;
};
int main()
{Stack<int>st1;Stack<int>st2;//做不到这两个栈存不一样的return 0;
}

我们使用非类型模板参数

//template<class T,size_t N>
template<class T,size_t N=10>//也可以给缺省值class Stack
{
private:T _a[N];int _top;
};
int main()
{Stack<int> st0;//10Stack<int,20> st1;//20Stack<int,200> st2;//200return 0;
}

浮点数,类对象以及字符串是不允许作为非类型模板参数的

非类型的模板参数必须在编译期就能确认结果

template<class T, double N = 10.2>class St
{
private:T _a[N];int _top;
};

2.模板的特化

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

2.1函数模板的特化

特化不能单独存在,要在函数模板的基础上叠加

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class Date
{
public:Date(int year = 1900, int month = 1, int day = 1): _year(year), _month(month), _day(day){}bool operator<(const Date& d)const{return (_year < d._year) ||(_year == d._year && _month < d._month) ||(_year == d._year && _month == d._month && _day < d._day);}bool operator>(const Date& d)const{return (_year > d._year) ||(_year == d._year && _month > d._month) ||(_year == d._year && _month == d._month && _day > d._day);}friend ostream& operator<<(ostream& _cout, const Date& d);
private:int _year;int _month;int _day;
};ostream& operator<<(ostream& _cout, const Date& d)
{_cout << d._year << "-" << d._month << "-" << d._day;return _cout;
}
//函数模板
template<class T>
bool Less(T left, T right)
{return left < right;
}
//函数模板支持特化
//特化
//不能独立存在,要在函数模板的基础上写,不能单独存在
//期望按照指向的内容去比较
template<>
bool Less<Date*>(Date* left, Date* right)
{return *left < *right;
}int main()
{cout << Less(1, 2) << endl;Date d1(2022, 7, 7);Date d2(2020, 6, 6);cout << Less(d1, d2) << endl;Date* p1 = new Date(2023, 5, 2);Date* p2 = new Date(2023, 4, 2);cout << Less(p1, p2) << endl;return 0;
}
//1
//0
//0

有现成的就用现成的,也相当于特殊化处理了

//我们也可以使用普通函数
bool Less(Date* left, Date* right)
{return *left < *right;
}

2.2类模板的特化

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class Date
{
public:Date(int year = 1900, int month = 1, int day = 1): _year(year), _month(month), _day(day){}bool operator<(const Date& d)const{return (_year < d._year) ||(_year == d._year && _month < d._month) ||(_year == d._year && _month == d._month && _day < d._day);}bool operator>(const Date& d)const{return (_year > d._year) ||(_year == d._year && _month > d._month) ||(_year == d._year && _month == d._month && _day > d._day);}friend ostream& operator<<(ostream& _cout, const Date& d);
private:int _year;int _month;int _day;
};ostream& operator<<(ostream& _cout, const Date& d)
{_cout << d._year << "-" << d._month << "-" << d._day;return _cout;
}template<class T1,class T2>
class Data
{
public:Data() { cout << "Date<T1,T2>" << endl; }
private:T1 _d1;T2 _d2;
};
//全特化
template<>//!!!必须有
class Data<int, int>
{
public:Data() { cout << "Data<int,int>" << endl; }
};
//偏特化    ---    特化部分参数
template <class T1>//需要一个模板参数可以留一个
class Data<T1, int>//得写全
{
public:Data() { cout << "Data<T1,int>" << endl; }
};
//偏特化  ---  两个参数偏特化为指针类型--对类型的进一步限制
template <class T1,class T2>
class Data<T1*, T2*>
{
public:Data() { cout << "Data<T1*,T2*>" << endl; }
private:
};
//两个参数偏特化为引用类型
template <typename T1, typename T2>//也可以是template <class T1,class T2>
class Data<T1&, T2&>
{
public:Data() { cout << "Data<T1&,T2&>" << endl; }
private:
};int main()
{Data<int, int> d1;Data<int, char> d2;Data<char, char> d3;Data<char, int> d4;Data<char*, int*> d5;Data<int*, int*> d6;Data<int&, int&> d7;return 0;
}//Data<int,int>
//Date<T1,T2>
//Date<T1,T2>
//Data<T1,int>
//Data<T1*,T2*>
//Data<T1*,T2*>
//int
//int
//Data<T1&,T2&>//偏特化以后还是原类型

3.模板分离编译

分离编译:

一个程序/项目由若干个源文件共同实现,而每个源文件单独编译生成目标文件,最后将所有目标文件链接起来形成单一得可执行文件得过程

a.h   a.cpp  test.cpp

预处理:展开头文件,条件编译,宏替换,去掉注释

     a.cpp->a.i   test.cpp->test.i

编译:检查语法,生成汇编代码

     a.i->a.s      test.i->test.s

汇编:汇编代码转换成二进制的机器码

      a.s->a.o      test.0

链接:合并在一起,并且没有确定地址的函数,要确定地址等工作生成可执行程序

      a.o  

                 ---> a.out

      test.o

链接时,Func可以链接成功,Add无法链接成功

test.i 中知道Add需要实例化成int和double各一份Add函数,但是他只有声明没有定义

a.i 中有Add的定义,但是不知道要实例化模板成什么类型

//a.i 定义template<class T>
T Add(const T& left, const T& right);
void Func(int x);
template<class T>
T Add(const T& left, const T& right);
{return left + right;
}
void Func(int x)
{cout << "void Func(int x)" << endl;
}//test.i  声明
template<class T>
T Add(const T& left, const T& right);
void Func(int x);
int main()
{Add(1, 2);Add(1.1, 2.2);Func(1);return 0;
}

解决:

1).cpp 中显示实例化,但是不好用

增加一个类型就不行了,每增加一个新类型就得实例化

//a.cpp#define _CRT_SECURE_NO_WARNINGS 1#include"a.h"//template<class T>
//T Add(const T& left, const T& right)//void Func(int x)template<class T>
T Add(const T& left, const T& right)
{return left + right;
}
void Func(int x)
{cout << "void Func(int x)" << endl;
}
//显式实例化也可以实现声明和定义分离
template
int Add(const int& left, const int& right);
template
double Add(const double& left, const double& right);//a.h#pragma once#include<iostream>
using namespace std;//放声明
template<class T>
T Add(const T& left, const T& right);
template<class T>
T Add(const T& left, const T& right);
void Func(int x);//Test.cpp#define _CRT_SECURE_NO_WARNINGS 1#include"a.h"int main()
{
cout<<Add(1, 2)<<endl;
cout<<Add(1.1, 2.0)<<endl;
Func(1);
return 0;
}//3
//3.1
//void Func(int x)
2)避免声明和定义分离,直接定义在.h,不存在链接要去找的问题

这样就都可以了

//a.cpp#define _CRT_SECURE_NO_WARNINGS 1#include"a.h"void Func(int x)
{cout << "void Func(int x)" << endl;
}//a.h#pragma once#include<iostream>
using namespace std;//放声明
template<class T>
T Add(const T& left, const T& right)
{return left + right;
}
void Func(int x);//Test.cpp#define _CRT_SECURE_NO_WARNINGS 1#include"a.h"int main()
{
cout<<Add(1, 2)<<endl;
cout<<Add(1.1, 2.0)<<endl;
cout << Add('a', 'x') << endl;
Func(1);
return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/3855.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

diffusion model 学习笔记

条件引导的 diffusion 对于无条件的DDPM 而言 p ( x t ∣ x 0 ) ∼ N ( α t ˉ x 0 , 1 − α t ˉ ⋅ I ) p(x_t | x_0) \sim \mathcal{N}( \sqrt{\bar{\alpha_t}} x_0, 1-\bar{\alpha_t} \cdot \mathrm{I} ) p(xt​∣x0​)∼N(αt​ˉ​ ​x0​,1−αt​ˉ​⋅I) 可以得到…

阿里云高并发测试-Redis缓存机制

创建接口 这里使用的是阿里云提供的接口服务直接做的测试&#xff0c;接口地址 curl http://localhost:8080/initData?tokenAppWithRedis 这里主要通过参数cacheFirstfalse和true来区分是否走缓存&#xff0c;正常的业务机制可能是通过后台代码逻辑自行控制的&#xff0c;这…

设计卷积神经网络CNN为什么不是编程?

上一篇&#xff1a;《搞清楚这个老六的真面目&#xff01;逐层‘剥开’人工智能中的卷积神经网络&#xff08;CNN&#xff09;》 序言&#xff1a;现在让我们开始走进卷积神经网络&#xff08;CNN&#xff09;的世界里。和传统编程完全不同&#xff0c;在人工智能的程序代码里…

气象仿真数据在光伏行业里面的作用

选址与规划 确定资源潜力区域&#xff1a;不同地区的太阳能资源、气候条件差异很大。通过对大量的气象仿真数据进行分析&#xff0c;可以准确评估不同地区的太阳辐射强度、日照时长、温度、湿度、风速风向以及降水情况等气象要素。规避潜在风险&#xff1a;一些地区可能存在极…

鸿蒙开发——进程模型与进程通信

1、进程模型 ❓ 什么是进程&#xff1f; 进程是一个正在执行的程序的实例。当我们启动一个程序时&#xff0c;操作系统会创建一个进程&#xff0c;分配给它所需的资源&#xff0c;如内存和CPU时间。每个进程至少有一个线程&#xff0c;即执行线程&#xff0c;负责执行程序的指…

Pod安装软件将CDN改为国内的镜像

1、碰到错误 在pod install的时候碰到以下的下载错误&#xff1a; 文字错误如下&#xff1a; CDN: trunk URL couldnt be downloaded: https://cdn.jsdelivr.net/cocoa/Specs/5/b/d/OpenCV/2.4.11/OpenCV.podspec.json Response: Timeout was reached CDN: trunk URL couldn…

Windows常用命令-病毒

1.常见端口对应的服务 ftp 21 tenlnet 23 80 web 80-89可能是web 443 ssl心脏滴血漏洞以及一些web漏洞测试 445 smb 1433 mssql 1521 oracle 2082/2083 cpanel主机管理系统登陆(国外用的较多) 2222 da虚拟主机管理系统登陆(国外较多) 3128 squid代理默认端口-漫游内…

DDD中的一些基础概念 观点摘录

系统复杂度来源于哪&#xff1f;也就是DDD存在意义 软件系统的复杂性主要体现在三个方面。 隐晦&#xff1a;一是抽象层面的隐晦&#xff0c;抽象系统时&#xff0c;每个人都有自己特定的视角&#xff0c;你需要站在对方的角度才能明白他为什么这么做&#xff1b;其次是实现层…

统信UOS开发环境支持shell

内置了Bash等流行的Shell环境,用户可编写自动化脚本,极大地提高了系统管理和应用开发效率。 文章目录 一、环境部署1. shell开发环境安装2. shell开发环境配置二、代码示例shell开发案例三、常见问题1. 文件处理2. 错误处理3. 跨平台兼容性一、环境部署 1. shell开发环境安装…

使用compare做简单的点云滤波,并另存为文件

一、打开compare软件后&#xff0c;打开一个pcd文件 二、点击显示的pcd文件对象&#xff0c;出现如图黄色框框 三、点击上边的菜单栏的这个标志 四、出现如下图&#xff0c;此时调整红绿蓝就可以简单的做一下背景的滤波操作 五、我调整蓝色按钮后将背景点云去除&#xff0c;点…

布谷语音源码服务器搭建环境及配置流程

布谷语音源码部署环境安装要求&#xff08;只有在相同的环境下才更容易避免一些不必要的麻烦&#xff09;&#xff1a;●安装Center OS 7.9&#xff0c;我们自己的服务器使用的是7.9建议相同系统&#xff0c;非强制●安装宝塔环境&#xff08;强烈推荐使用&#xff09;●安装软…

奥数与C++小学四年级(第二十题 猜猜看)

参考程序代码&#xff1a; #include <iostream> using namespace std;int main() {// 集合 {1, 2, 3, 4, 5, 6, 7, 8}int set[] {1, 2, 3, 4, 5, 6, 7, 8};// 枚举所有可能的 5 个数for (int i 0; i < 8; i) {for (int j i 1; j < 8; j) {for (int k j 1; k…

关于游戏加加不可以在cs2中显示的解决方案

输入的代码如下 -allow_third_party_software 1.打开steam 右键cs2&#xff0c;打开属性。 然后再这里填上这个代码就可以了

QGIS:HCMGIS插件

插件GitHub地址&#xff1a;https://github.com/thangqd/HCMGIS。 以下对HCMGIS插件进行简单介绍&#xff0c;并演示如何进行地图数据下载。 插件简介 HCMGIS - Basemaps, Download OpenData, Batch Converter, VN-2000 Projections, and Field Calculation Utilities for QGI…

康姿百德典雅床垫功效价格双佳,上班族睡眠升级的秘密武器

卓越支撑&#xff0c;透气之选 —— 康姿百德集团公司典雅床垫引领睡眠新风尚 选择一款优质的床垫对于确保良好的睡眠至关重要&#xff0c;尤其是对于每日辛勤工作的上班族而言。一天结束后&#xff0c;躺在舒适的床垫上&#xff0c;享受深度睡眠的美好体验&#xff0c;是最放…

103 - Lecture 3

SQL - Table and Data Part 2 一、Table Constraints Table constraints can be defined when creating tables. But you can also add constraints to an existing table. 1. Syntax of Constraints • General Syntax: CONSTRAINT name TYPE details; • 约束名称是为了以后…

前端 算法 双指针

文章目录 三数之和移动零盛最多水的容器接雨水 三数之和 leetcode 三数之和 题目链接 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请你返回所有…

nuPlan最新SOTA,香港科技大学发布基于学习决策范围内的规划PlanScope

nuPlan最新SOTA&#xff0c;香港科技大学发布基于学习决策范围内的规划PlanScope Abstract 在自动驾驶的背景下&#xff0c;基于学习的方法在规划模块的开发中表现出了很大的潜力。在规划模块的训练过程中&#xff0c;直接最小化专家驾驶日志与规划输出之间的差异是一种广泛采…

MATLAB实现人工免疫网络算法(Artificial Immune Network Algorithm, AINA)

1. 免疫网络算法简介 生物免疫系统是自然界中最复杂、最有效的自适应系统之一&#xff0c;它能够识别并清除入侵的病原体&#xff0c;同时保持对自身细胞的忍耐。免疫网络算法是一种借鉴生物免疫系统原理和机制的计算模型 2.算法流程 3.MATLAB代码 完整代码见: https://down…

MySQL初学之旅(1)配置与基础操作

目录 1.前言 2.正文 2.1数据库的发展历程 2.2数据库的基础操作 2.2.1启动服务 2.2.2创建与删除数据库 2.2.3数据类型 2.2.4创建表与删除表 2.3MySQL Workbench基础使用简介 3.小结 1.前言 哈喽大家好吖&#xff0c;今天博主正式开始为大家分享数据库的学习&#xff…