Learning a Part of C++(for ACM/ICPC) (4) 模板初步

ABAP 平台下配置 OAuth 2.0 Authorization Code 授权类型的完整指引 本文是面向ABAP管理员和SAP开发者的OAuth 2.0授权码配置实战指南。文章详细介绍了在ABAP平台启用Authorization Code的完整流程,包括前置条件检查(如TLS配置和系统用户准备)、SOAUTH2事务码中各字段配置要点(授权类型启用、Redirect URI设置、授权码有效期等)、Scope分配规则以及验证方法。通过一个销售订单OData接口的实际案例,说明了如何将抽象规范转化为具体配置。最后提供了多种验证方式(事务码测试、端点测试和Postman测试)以及关键配置参数(如授权码有效 阅读详情

在真的跳入使用STL之前,我们最后来认识下一个重要概念——模板(其他语言里称之为泛型)。

1、初识模板——模板函数

在这里思考了很久,我们还是从输入挂开始吧。 
首先一起来看看夏天的风的输入挂 (输入输出加速):

Exp 4.01 
编译运行以下代码,输入12345 12345678901234 12345678901234,观察scan_d()的行为、printf()和out()输出的结果的差异

 
  1. #include <stdio.h>
  2. #include <math.h>
  3. template <class T>
  4. inline void scan_d(T &ret) {
  5. char c; ret=0;
  6. while((c=getchar())<'0'||c>'9');
  7. while(c>='0'&&c<='9') ret=ret*10+(c-'0'),c=getchar();
  8. }
  9. inline void out(int x){
  10. if(x>9) out(x/10);
  11. putchar(x%10+'0');
  12. }
  13. int main(){
  14. int a=0;
  15. long long b=0,c=0;
  16. scan_d(a);
  17. scan_d(b);
  18. scan_d<int>((int&)c);
  19. printf("%d %I64d %I64d\n",a,b,c);
  20. out(a); putchar(' '); out(b); putchar(' '); out(c);
  21. return 0;
  22. }

首先分析scan_d()这个模板函数的写法。 
第一行:template <class T> 
template<>表明下面是个模板,<>内的东西,我们称作模板参数列表,具体在这里,class T表示声明了一个T,T待填,T应该填上一个类型名。 
(据说在这里,class和typename是同义词,也就是说,你可以写作template <typename T>,我个人不确定,对此半信半疑) 
所谓T待填,就是在这个函数里面,任何出现T的地方,都将被实际类型替代。

比如上面的scan_d(a);scan_d(b); 
编译器会检查a和b的类型,a是int,b是long long, 
那编译器知道了, 
调用a的时候,那个T应该是int,然后生成了一份副本:

 
  1. inline void scan_d(int &ret) {
  2. //源代码上,内容一致
  3. }

调用b的时候,那个T应该是long long,然后生成了一份副本:

 
  1. inline void scan_d(long long &ret) {
  2. //源代码上,内容一致
  3. }

在里面做运算的时候,对a用int的运算,对b的调用,用long long的运算 
——int的运算可比long long的运算快出一些来。

当然,你可也以强制指定类型,比如上面写的scan_d<int>((int&)c);。 
这样,强制告诉编译器,对scan_d这个模板函数,我这里的调用指定T是int。

——等等,为什么函数参数那么别扭,带着(int &)? 
——指定了T是int后,因为C++是个强类型语言,他会非常认真的确认,你传入的参数是不是和你指定的类型匹配,而long long类型的c与这里int的要求不匹配,如果不进行强制类型转换,会直接导致,编译错误,提示:

[Error] no matching function for call to 'scan_d(long long int&)

我们用几句简单的话,总结一下:

  • 模板函数,第一行是template<>,说明这是一个模板函数。
  • 尖括号内,放入一些待填信息(模板参数列表),比如class T1, typename T2。
  • 之后函数的声明和实现中,所有写着T1、T2的地方,都会被编译器替换成相应的类型(或数值,具体在下面的模板类中说明),然后编译生成一种版本的函数调用。
  • 对模板函数来说,编译器还会根据你传入的参数,推导待填的类型名应该是什么。
  • 当然,使用模板函数时,我们也可以强制指定参数类型,具体语法函数名<模板参数列表>(函数参数列表)

Tips 4.01 
为什么这样的输入挂会有加速效果? 
scanf()/printf()是有缓冲区的,按理说这样应该很高效了才对。 
可是注意到,前面有格式化字符串。比如你要读取10万个int,每次调用scanf都会重复解析这个格式化字符串,然后再去读入,就非常慢了。 
输入挂直接确定了你要读入的数据类型,省去了字符串解析这个步骤,做到了提速。 
(当然还有更快的输入/输出挂,一口气读入大量数据,一口气写出大量数据,就更好了)


Exercise 4.01 
注意到上面我们在用out()函数输出的时候,普通函数out()会把所有传入的参数视作int类型,甚至long long也被转换成int,导致输出错误。 
请把out()函数修改成模板函数,使其根据传入的参数,确定是要当做int输出(取模运算快一些),还是当做long long输出(取模运算慢一些,但是能正确输出long long) 
(如果感兴趣,请试着加上对负数的支持)

2、模板类

思考这个情况: 
写BFS的时候,我们要把扩展出的节点信息压入队列里。 
如果是实现SPFA的时候,节点信息也许只有一个点的编号 
如果是网格图上走的时候,节点信息是x和y,2个参数 
如果转向还记做一步,那节点信息是x,y和方向,3个参数 
……………………………… 
信息很多,但都用来表示位置的时候,那不放设计一个结构体吧:

 
  1. struct State{
  2. int x,y,direction;
  3. //还有相应的构造函数等
  4. }

这样,只要压入一个State结构体的实例进队列就好了。

如果我们直接数组模拟一个队列,有个问题——不可扩展啊! 
第一次是存int元素的队列,之后要改一下,改成存State的队列,得修改压队列函数的参数、出队列函数的返回值、存队列的数组的类型,等等等等。 
不仅改的烦,定了类型以后还不可扩展、不可复用。

那么我们想想,如果对队列这种通用数据结构,用泛型实现,不就一劳永逸了?

Exp 4.02 
编译运行以下代码,观察结果,理解泛型类的写法与使用。

 
  1. #include <stdio.h>
  2. /************
  3. 循环队列,常见的数组模拟队列的实现方案
  4. 具体思想是,维护2个指针,一个头一个尾,从0开始往后移动,
  5. 移到MaxSize-1的时候,回到0
  6. 就相当于,看做MaxSize-1这个单元之后的下一个元素是0
  7. ************/
  8. template<class X,int MaxSize>
  9. struct LoopQueue{
  10. X data[MaxSize];
  11. int head,tail,sz;
  12. LoopQueue(){
  13. init();
  14. }
  15. void init(){
  16. head=0;tail=0;sz=0;
  17. }
  18. void push(const X& x){
  19. data[tail]=x;
  20. tail++;if(tail>=MaxSize)tail-=MaxSize;
  21. sz++;
  22. }
  23. void pop(){
  24. head++;if(head>=MaxSize)head-=MaxSize;
  25. sz--;
  26. }
  27. X front(){
  28. return data[head];
  29. }
  30. int size(){
  31. return sz;
  32. }
  33. bool empty(){
  34. return head==tail;
  35. }
  36. };
  37. LoopQueue<int,20> q;
  38. int main(){
  39. for(int i=1;i<=10;i++){
  40. q.push(i);
  41. }
  42. while(!q.empty()){
  43. printf("%d ",q.front());
  44. q.pop();
  45. }
  46. puts("\n==========");
  47. for(int i=15;i<=30;i++){
  48. q.push(i);
  49. }
  50. while(!q.empty()){
  51. printf("%d ",q.front());
  52. q.pop();
  53. }
  54. return 0;
  55. }

事实上泛型类在真的你去写一个的时候,没那么恐怖,和模板函数非常相似。 
同样的,第一行template<模板参数列表>,之后正常的声明一个类,待填的地方用参数列表里的名字填进去,最后实例化这个模板类的时候,用类名<模板参数列表> 类的实例名;的格式(比如上面的LoopQueue<int,20> q;),然后使用的时候并没有任何特别的,只要正常的,使用这个类的方法,就行了。 
注意:模板类,你就不要指望编译器帮你做类型推定了,你必须老老实实的写出模板参数


当然,注意到,这里有个模板参数,是个int类型的! 
是的,你们没看错,是可以有一个int类型(甚至其他具体类型)的参数,实例化的时候直接int对应的填进去就行了。 
(这个在STL的bitset中有使用,会介绍的。)


补充一句: 
还记得第一讲提到的,C++里函数参数可以有默认值吗? 
模板参数也是可以有默认值的,比如我可以声明:

 
  1. template<class X,int MaxSize=10000>

这样允许你,如下的实例化:

 
  1. LoopQueue<int> qint; // MaxSize会被当做10000
  2. LoopQueue<int,15> q2; //MaxSize为15的一个,能存int类型数据的LoopQueue

Tips 4.02 
如果用过STL提供的queue和stack的同学,会注意到,我这里的实现实际上是在模仿STL里提供的方法。为什么呢? 
说来话长了…… 
一次比赛,队友写出了一题,然后超时,Claris怀疑是当时用了STL的stack的锅,然后选择让我手写一个数组模拟的,结果过了…… 
因为stack和queue他们是二次封装的容器,底层的容器(或者说,空间管理)是deque(之后STL部分会介绍),这个deque慢的人实在受不了…… 
虽说,的确,很少有情况会卡你使用STL的queue和stack,但是,就算出现了,手写一个也不应该有困难。


Exercise 4.02 
1、既然我们提到了,我用泛型实现过一个stack(栈),那不妨试试?(说不好有天你就用了……)

2、(小米电话面试,远程共享代码窗口,真题) 
使用C++语言实现一个双端队列(双端队列,一个允许从头部或尾部插入/删除的队列,也就是,支持4种修改元素操作)模板类Deque<T>,实现要求使用静态数组方式存储,在初始化时指定静态数组的大小(如果超过大小,不需要扩展大小,只需要提示错误即可),并实现以下方法(此处指给出函数名,请自己设计函数签名(函数参数和返回值)): 
首尾添加元素:push_front(), push_back() 
首尾删除元素:pop_front(), pop_back() 
首尾获取元素:front(), back()
 
请注意,请尽量高效实现(所有操作的复杂度都应该为O(1))

【DRAM存储器四十三】LPDDR5介绍--寻址 简要说明LPDDR5 X16、x8 die的寻址 阅读详情

相关推荐

ch32v103xx 烧写

烧写方式 串口uart, usb,swd(wch link)但不建议按此使用,参官方说明。

qq_39239990的博客 637

CrayonKe_ACM-ICPC算法模板(2021-8-4)

语法基础、STL memset(array,0,sizeof(array)); 赋值0 memset(array,63,sizeof(array)); 赋值+∞ memset(array,192,sizeof(array)); 赋值-∞ memset(array,255,sizeof(array)); 赋值-1 常规算法 动态规划 单调队列优化DP #include<bits/stdc++.h> #define ll long long using namespace std; int n

CrayonKe的博客 431

VisionMaster -Group循环、数组数据格式化

这里创建一个格式化工具,按照自己想要的模式格式化刚刚输出的数据。因为是检测多个物体,所以这里选择输出的是数组。第一次的模板很不满意,反复调整参数也没好,边缘不整齐,强迫症患者受不了。实测如果输入设置太多,会导致模块失效,所以尽量选择需要的少量参数。这里要打开循环使能,循环数值就是高精度匹配的匹配个数。Group输出设置里选择刚刚建立的数据集。左边是主流程,右边是组合模块内部流程。修改采图这里的曝光值,图像提亮一点。建一个数据集,把想要的数据收集起来。用TCP助手测试一下OK。成功得到了想要的数据。

weixin_69505365的博客 4530

二分模板

二分 二分模板 1.循环必须是l < r 2.if判断条件看是不是不满足条件, 然后修改上下界 3.若if else后是r = mid - 1,则前面mid 语句要加1 4.出循环一定是l == r,所以l和r用哪个都可以 二分只有下面两种情况 1:找大于等于给定数的第一个位置 (满足某个条件的第一个数) 2:找小于等于给定数的最后一个数 (满足某个条件的最后一个数) // 判断条...

Stormjing的博客 373

工业缺陷检测深度学习方法综述

异常:点异常、 上下文异常和集群异常。点异常:又称为离群值 (outliers)[9], 描述数值上偏离正 常样本的独立数据。与异常相近的概念还包括新颖点(novelty)和分布外数据。上下文异常:同样描述数据点,其数值属于正常范围,但不符合局部上下文规律。集群异常:描述一系列相关数据的集合,集合中的每一个实例的数值在单独考察时都处于正常值域,但集 合整体的相关性特征不服从正常模式。一般的图像异常检测往往仅需区分正常与异常样本,而工业缺陷检测更关注于检测 图像中的异常像素.

2301_80355452的博客 1843

360加固DEX解密与ELF修复技术解析

本文深入解析了360加固APK的逆向分析技术,重点探讨了其DEX解密与ELF文件修复的核心流程。通过动态调试与Frida脚本,详细拆解了壳的启动机制、反调试绕过、自实现Linker技术,并还原了基于RC4和自定义算法的多层DEX解密过程,为移动安全研究人员提供了实用的实战分析思路。

alice7model的博客 701

输入数据加速 scan_d();

#include #include template inline bool scan_d(T &ret){ char c;bool sgn; if(c=getchar(),c==EOF)return 0; while(c!='-'&&(c'9'))c=getchar(); sgn=(c=='-'); ret=sgn?0:(c-'0

xiaoyu1_1的专栏 889

【Android】条形码/二维码扫描——ZXing源码分析

正在更新中 针对3.2.1版本源码 与其他版本代码可能会有出入,但核心思想基本不变。 首先从com.google.zxing.client.android包中的目录结构分析:Book:这个文件夹中有5个类: BrowseBookListener 实现了adapter的点击事项响应,通过获取ISBN,然后跳转到Google books中查询响应的详细信息。 SearchBookContents

年轻的学徒 2453

2018.11.22 训练日记

这个周,,claris的博客还是没怎么看,就看了两篇,,,真是看不动 了,把数学模型的论文莫出来了!!!然后做了几套CF的题,练练手,练练思维。 昨晚上拉的题是去年多校的第三套。。三个小时,打的也是一般吧,, 先是一个水题,队友直接A了,然后,H是一个数学推公式的,但是我们直接猜了,,,n的k次方,直接取模即得答案。但是,,,忘记加case,,,WA+1 然后我觉得C能做,然后二分+树状数组...

AAAAAAAC的博客 236

9 硬件工程师笔面试高频知识考点真题解析——运算放大器

运算放大器(运放)摘要 运放是一种高增益、差分输入的模拟集成电路,具有虚短(线性区输入电压相等)和虚断(输入电流为零)特性,支持负反馈(线性放大)和开环/正反馈(饱和区比较)两种工作模式。关键特性包括高输入阻抗、低输出阻抗,理想运放参数(如无限增益)与实际参数(如有限带宽)的差异。 选型要点: 信号特性:直流/低频信号关注失调电压(Vos)、温漂;高频信号侧重带宽(GBW)和压摆率(SR)。 电源条件:单/双电源供电、电压范围及功耗需求(如电池设备需低静态电流)。 精度与噪声:微弱信号需低噪声运放,高精度场

XU157303764的博客 1675

uniapp - [微信小程序] 实现点击预览各种文件 pdf文档、视频mp4、mp3音乐、图片图像、word/excel/ppt 等,uniapp小程序文件预览功能(详细示例代码,一键复制开箱即用)

uniapp,uniapp微信小程序,支付宝小程序平台端,uniapp实现文件在线预览,uniapp微信小程序怎么实现预览视频mp4,mp3音乐,图片,office文档,小程序平台如何在线预览word/excel/ppt文档,uniapp实现小程序端的文件查看功能,uniapp小程序端实现pdf文件预览,uniapp纯前端预览PDF、DOC、DOCX、图片、视频,uni-app文档、图片预览查看,uniapp文档预览功能,uniapp小程序端文件预览,uniapp小程序平台纯前端解析word,pdf,xls

✅ 精选推荐文章 1万+

第一次参加acm-icpc现场赛(2016大连赛区)总结

第一次参加现场赛即打铁,这种感觉真的很难受,然而更难受的是与我们同时参加2016ccpc合肥赛区的我校另一队伍斩获铜牌,当然铜牌已经对我们这种弱校虽算不上多么大的荣耀,但也算是有点成就了。但就我个人而言,我们队的努力程度应该高于这支铜牌队伍吧!虽说,一场是ccpc,一场是icpc,但这种初战即铁,另一支队伍初战拿铜的感受,我想=应该只有我和我的队友能够体会到。抛开这些空话,我想为我们的失败来以借口

mystery_guest的博客 3466

Autosar进阶专栏索引

Autosar进阶专栏索引

赞的博客 3540

Learning a Part of C++(for ACM/ICPC) (1) 简介

没什么高大上的目标,就是简单介绍一下对ACM/ICPC来讲比较实用的C++知识,顺带把最近做题中使用C++所踩过的坑给记载下来,各位谨防中招。

Doge 697

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Learning a Part of C++(for ACM/ICPC) (3) 运算符重载

我们接着前一篇留下来的坑,继续讲: 前一篇中,我们提到:(A.add(B)).num_multiply(10.0)这样的形式看上去冗长,还不够自然。有一个办法解决,那就是:运算符重载

Doge 874

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Learning a Part of C++(for ACM/ICPC) (2) 类的封装

接下来,我们将先面对面向对象这个概念所带来的一些特性。 在这篇和下一篇有关运算符重载的内容里,我们将围绕设计一个能表示点和向量的结构体的基础上开始扩充,扩充成一个有一定实用意义的简单类,感兴趣的同学可以去继续加强,然后成为自己几何模板的基础。

Doge 482

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Learning a Part of C++(for ACM/ICPC) (5) STL概览

Finally,花了这么多时间,做足了有的没的的铺垫以后,我们可以开始看看,ACM中有点泛滥的STL了。

Doge 447

Learning a Part of C++(for ACM/ICPC) (7) STL中的string和bitset

然后我们来讲解一下STL中的2个,呃,存特定类型数据的类。

Doge 914

【HDU6196 2017 ACM ICPC Asia Regional Shenyang Online C】【爆搜 + 剪枝】happy happy happy 爸爸儿子轮流两头取数 爸爸想输且输少

happy happy happy Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 143    Accepted Submission(s): 22 Problem Description Today, Bob

snowy_smile的博客 2180

【2021杭电多校第三场】1010Road Discount

题目链接:https://acm.hdu.edu.cn/showproblem.php?pid=6982 题目大意:给n个点m条边,每条边有两个边权(黑边和白边),问求恰好包含恰好 k(k属于0到n-1 )条黑边的最小生成树。 解题思路:其实是经典的求k条黑边的最小生成树问题(然而我不会) 以下是claris的题解:这是一个经典问题,令 f(k) 表示包含恰好 k 条黑边的最小生成树的边权和,则 f(k) 是一个凸函数,求出 f(k) 的方法为: 1、选择参数 c,将每条黑边的边权都加上 c。 2

Chral317的博客 379

ACM学习参考博客

OI大神博客   https://www.cnblogs.com/TheRoadToTheGold/category/985514.html OI届的小混混(dalao):https://www.cnblogs.com/zwfymqz/p/9338689.html codeforces-Petr :http://petr-mitrichev.blogspot.com/ WJMZBMR-clj...

Wind_bow的博客 1万+

ACM及OI大佬的博客(待补充)

codeforces-Petr :http://petr-mitrichev.blogspot.com/WJMZBMR-clj:http://wjmzbmr.com/小岛:http://www.shuizilong.com/house/卿学姐:http://www.cnblogs.com/qscqeszehzwer:http://hzwer.com/巫泽俊:http://blog.watashi....

sortmin的博客 2989

西安集训第七天-----claris叫你常见的数据结构维护技巧

呵呵,“常见”的技巧 这是一辆高铁,全程膜claris

qq_24664053的博客 669

HDU 5661 Claris and XOR

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5661题目大意:给你两个区间,每个区间的范围在1-10^18,从两个区间中各挑选一个数,x , y,为这两个区间异或的最大值是多少题解:我们要尽可能的使最高位为1,只有一种情况最高位是0,那就是 当两个数最高位都必须取1时,那么最高位就肯定是0,其它的情况最高位取到1,每次都取让最高位等于1的方案就好了

仰望星空 892

template &ltint inst&gt 的功用

template<int inst>的作用最近在看STL源码解析,里面有讲到STL的Allocator,有一个小问题不太理解,求高手指导. 第57页给出了SGISTL中这样的定义: template<intinst> class__malloc_alloc_template{ ....... } 书上说,这个定义中,没有"template类型参数",至...

MashiMaroJ的专栏 1581
上一篇: Learning a Part of C++(for ACM/ICPC) (3) 运算符重载
下一篇: Learning a Part of C++(for ACM/ICPC) (5) STL概览
ACDoge
博客等级 码龄10年 8粉丝 62原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值