首页 文章 精选 留言 我的

精选列表

搜索[学习],共10000篇文章
优秀的个人博客,低调大师

EduSoho:免费部署在线学习平台

版权声明:转载请注明出处:http://blog.csdn.net/dajitui2024 https://blog.csdn.net/dajitui2024/article/details/79396608 EduSoho帮助培训机构和个人以最低成本、最快速度建立自己的在线教学网站,采用PHP 5开发,使用mysql数据库。 框架使用Symfony2.3 的视图层 + 自主研发的服务容器框架。更多帮助文档:http://www.edusoho.com/helphttp://www.qiqiuyu.com/ 1、基础配置: 官方推荐的配置是LNMP,即Linux+Nginx+MySQL+PHP 选择操作系统(Linux) 推荐使用Ubuntu,Fedora,CentOS,Gentoo。 选择Web服务器(Nginx或Apache2) Web服务器,官方推荐:Nginx或Apache2。关于Nginx:下载地址: http://nginx.org/en/download.html版本推荐: 1.0以上关于Apache2:下载地址: http://httpd.apache.org/download.cgi推荐版本: 2.0以上 选择MySQL数据库 MySQL数据库推荐版本:5.0以上。下载地址:http://www.mysql.com/downloads 选择PHP版本 版本: >= 5.5.0下载地址:http://cn2.php.net/downloads.php 注意:1. Linux 下需要关闭SeLinux ,不然安装完成页面会空白2.Nginx.conf中一定要配置client_max_body_size, 不然上传大文会卡住时 详细配置文档指导: Ubuntu14.04+Nginx+PHP+MySQL+EduSoho[推荐-标准环境-文档]Ubuntu 14.04+Apache+PHP+MySQL+EduSoho[文档]Ubuntu 12.04/14.04 以及 CentOS 6.x 一键安装EduSoho [推荐 - 快捷安装]Ubuntu14.04,使用Docker一键安装EduSohoCentOS 6.x + Nginx + PHP + MySQL + EduSoho[文档]CentOS 6.x + Apache+ PHP + MySQL + EduSoho[文档]CentOS 7 + Nginx + PHP + MySql + EduSohoCentOS 7 + Apache + PHP + MySql + EduSoho已预装EduSoho的Ubuntu 14.04 VMWare虚拟机AMH+LAMP安装EduSohoAMH+LNMP安装EduSohoWDCP + CentOS 6.x + EduSoho + Nginx

优秀的个人博客,低调大师

python-opencv学习笔记(二)

图像与原始字节之间的转换:从概念上,一个字节能表示0到255的整数,通常一个像素每个通道由一个字节表示。一个OpenCV图像是.array类型的二维或者三维数组。8位的灰度图像是一个含有字节值得二维数组。一个24位的BGR图像是一个三维数组,也包含了字节值,可以使用表达式访问这些值,如image[0,0]或者image[0,0,0]。第一个值表示y坐标,第二个值表示x坐标,第三个值为颜色通道。还可以使用image.item((0,0))或image.setitem((0,0),128)来访问像素和对像素进行操作。若一幅图像的每个通道为8位,则可以将其显式转换为标准的移位Python bytearray格式: byteArray=bytearray(image) bytearray含有恰当顺序的字节,可以通过显式转换和重构,得到numpy.array形式的图像: grayImage=numpy.array(grayByteArray).reshape(height,width) bgrImage=numpy.array(bgrByteArray).reshape(height,width,3) 下面介绍一个将含有随机字节bytearray转换为灰度图像和BGR图像: import cv2 import numpy as np import os randomByteArray=bytearray(os.urandom(120000)) flatNumpyArray=np.array(randomByteArray) grayImage=flatNumpyArray.reshape(300,400) cv2.imwrite('RandomGray.png',grayImage) bgrImage=flatNumpyArray.reshape(100,400,3) cv2.imwrite('RandomColor.png',bgrImage) 结果产生灰度图:和彩色图像:使用numpy.random.randint(0,256,120000).reshape(300,400)也可以并更加高效地生成Numpy数组。使用numpy.array访问图像数据:y.array结构针对数组操作有很好地优化,允许(bulk)操作。.array操作再OpenCV图像处理中会很方便使用,如对BGR图像的某一像素点进行操作,转换为白色像素点: import cv2 import numpy as np img=cv2.imread('time.jpg') img[0,0]=[255,255,255] cv2.imshow('1',img) cv2.waitKey() 用numpy.array函数来转换数组比普通的Python数组转换要快得多。方法: import cv2 import numpy as np img=cv2.imread('time.jpg') print(img.item(150,120,0)) img.itemset((150,120,0),255) print(img.item((150,120,0))) 使用numpy.array的原因:numpy.array处理这类问题进过很好地优化;通过Numpy的方法代码可读性更强。下面是对通道的操作,指定某一通道的所有值置为0: import cv2 import numpy as np img=cv2.imread('time.jpg') img[:,:,1]=0 cv2.imshow('1',img) cv2.waitKey() 注意:通过循环操作来处理Python数组的效率非常低,尽量避免;使用数组索引可以高效地操作像素,像素操作是一个高代价的低效操作,特别是在处理视频图像时,可用索引来解决这个问题。通过NumPy数组的索引访问原始图像:设置感兴趣区域(Region Of Interest ,ROI): import cv2 import numpy as np img=cv2.imread('time.jpg') my_roi=img[0:100,0:100] img[300:400,300:400]=my_roi cv2.imshow('1',img) cv2.waitKey() 要确保这两个区域大小相同。numpy.array获取图像的属性: import cv2 import numpy as np img=cv2.imread('time.jpg') print(img.shape) print(img.size) print(img.dtype) 结果: (1080, 1920, 3) 6220800 uint8 其中三个属性为:Shape:NumPy返回包含宽度,高度和通道数的数组,在调试图像类型调试时有用,如果图像是单色或灰度的,将不包含通道值。Size:该属性是指图像像素的大小Dtype:该属性会得到图像的数据类型(通常为一个无符号整数型的变量和该类型占的位数,比如uint8类型)

优秀的个人博客,低调大师

Python-OpenCV学习笔记(六)

颜色色域: 灰度色域,除去彩色信息将其转换成灰阶,灰度色域对中间处理有效,如人脸检测 BGR :每个像素点都是有一个三元数组来表示-HSV,H(Hue)色调,S(saturation)饱和度,V(Value)亮度 傅里叶变换:傅里叶变换可以区分图像哪里变换强,哪里变换不强,标记噪声区域,感兴趣区域,前景和背景等。在Python的Numpy中有快速傅里叶变换(FFT)包,其中包含了fft2()函数。图像的幅度谱是另一种图像,幅度谱呈现了原始图像在变化方面的一种表示:把一幅图像中明亮的像素放到图像中间,然后逐渐变暗,在边缘上的罪案,可以发现亮暗像素的分布及百分比。高通滤波器:例子: import cv2 import numpy as np from scipy import ndimage kernel_3x3 = np.array([[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]]) kernel_5x5 = np.array([[-1, -1, -1, -1, -1], [-1, 1, 2, 1, -1], [-1, 2, 4, 2, -1], [-1, 1, 2, 1, -1], [-1, -1, -1, -1, -1]]) img = cv2.imread("time.jpg", 0) k3 = ndimage.convolve(img, kernel_3x3) k5 = ndimage.convolve(img, kernel_5x5) blurred = cv2.GaussianBlur(img, (17,17), 0) g_hpf = img - blurred cv2.imshow("3x3", k3) cv2.imshow("5x5", k5) cv2.imshow("g_hpf", g_hpf) cv2.waitKey() cv2.destroyAllWindows() 导入模块后,定义一个3x3和5x5的核,然后读入以灰度的形式读入图像,因为NumPy的卷积只能是一维的用SCiPy的convolve()函数来解决。边缘检测:Opencv提供了许多边缘滤波函数,包括Laplacian(),Sobel()以及Scharr()。这些函数都会将非边缘区域转为黑色,将边缘区域转换为白色或其他颜色。但缺点是容易将噪声错误地识别为边缘。所以之前一般加一些滤波器。创建filters.py import cv2 import numpy as np import scipy.interpolate def strokeEdges(src ,dst ,blurKsize=7,edgeKsize=5): if blurKsize>=3: blurredSrc=cv2.medianBlur(src,blurKsize) graySrc=cv2.cvtColor(blurredSrc,cv2.COLOR_BGR2GRAY) else: graySrc=cv2.cvtColor(src,cv2.COLOR_BGR2GRAY) cv2.Laplacian(graySrc,cv2.CV_8U,graySrc,ksize=edgeKsize) normalizedInverseAlpha=(1.0/255)*(255-graySrc) channels=cv2.split(src) for channel in channels: channel[:]=channel*normalizedInverseAlpha cv2.merge(channels,dst) Canny边缘检测:Canny边缘检测算法复杂,有五个步骤,即使用高斯滤波器对图像进行去噪,计算梯度,在边缘上使用非最大抑制(NMS),在检测到的边缘上使用双阈值去除假阳性(false positive),最后还会分析所有边缘及其之间的连接,,以保留真正的边缘并消除不明显的边缘。 import cv2 import numpy as np img=cv2.imread("time.jpg",0) cv2.imwrite("canny.jpg",cv2.Canny(img,200,300)) cv2.imshow("canny",cv2.imread("canny.jpg")) cv2.waitKey() cv2.destroyAllWindows() 轮廓检测: import cv2 import numpy as np img = np.zeros((200, 200), dtype=np.uint8) img[50:150, 50:150] = 255 ret, thresh = cv2.threshold(img, 127, 255, 0) image, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) color = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) img = cv2.drawContours(color, contours, -1, (0,255,0), 2) cv2.imshow("contours", color) cv2.waitKey() cv2.destroyAllWindows() 代码先创造了一个200x200大小的黑色空白图像,接着在图像的中央放置一个白色方块,用到了np数组在切片上赋值的功能。接下来对对图像进行二值化操作,然后调用findContours()函数。该函数有三个参数:输入图像,层次类型和轮廓逼近方法。这个函数会修改输入图像,因此建议使用原始图像的一份拷贝(通过img.copy()来作为输入图像)。由函数返回的层次树相当重要:cv2.RETR_TREE参数会得到图形中的轮廓的整体层次结构,以此来建立轮廓之间的“关系”。如果只想用到最外面的轮廓,可以用到cv2.RETR_EXTERNAL。这对消除包含在其他轮廓中的轮廓有用。findContours()函数有三个返回值:修改后的图像,图像轮廓以及层次

优秀的个人博客,低调大师

Python-OpenCV学习笔记(五)

使用managers.CaptureManager提取视频流CaptureManager类能对异性差异进行抽象,并提供了更加高级的接口从获取流中分配图像,再将图像分配到一个或多个输出中(如图像文件、视频文件或窗口)。在VideoCapture类中初始化CaptureManager类,在应用程序主循环的每一次迭代中通常应调用CaptureManager中的enterFrame()和exitFrame()函数。在调用enterFrame()和exitFrame()函数之间,应用程序可能会设定通道属性并获取帧属性。通道属性的初始值为0.只有在多台摄像头的情况下,通道属性的初始值非0,。帧属性是调用enterFrame()函数时与当前通道状态对应的图像。可能会经常调用CapTureManager类的writeImage(),startWritingVideo()和stopWritingVideo()函数。在调用exitFrame()函数之前,会有延迟写入文件。并且,在调用existFrame()函数过程中,帧属性可能会在窗口中显示,这取决于应用程序代码是将WindowManager类作为CaptureManager的构造函数参数还是设置previewWindowManager属性。如果应用程序代码处理了帧属性,那么在记录文件和窗口中会有所体现。CaptureManager类有一个称为shouldMirrorPreview的构造函数参数和属性,如果想要帧在窗口中镜像,但不记录在文件中,可将shouldMirrorPreciew设置为True。Opencv不能为摄像头提供准确的帧速率。解决这个问题的方法是通过帧计数器和Python标准的time.time()函数来估计帧数率。创建一个名为managers.py,该文件包含了CaptureM的实现,这各实现结果很长分成几段,先导入包、构造函数和属性: import cv2 import numpy import time class CaptureManager(object): def __init_(self,capture,previewWindowManager=None,shouldMirrorPreview=False): self.previewWindowManager=previewWindowManager self.shouldMirrorPreview=shouldMirrorPreview self._capture=capture self._channel=0 self._enteredFrame=False self._frame=None self._imageFilename=None self._videoFilename=None self._videoEncoding=None self._videoWriter=None self._startTime=None self._framesElapsed=numpy.long(0) self._fpsEstimate=None def channel(self): return self._channel def frame(self): if self._enteredFrame and self._frame is None: _,self._frame=self._capture.retyieve() return self._frame def isWritingImage(self): return self._imageFilename is not None def isWritingVideo(self): return self._videoFilename is not None 大多数成员变量为非公有变量,这类变量名前会加一个下划线进行标识。这些非公有变量与当前帧的状态以及文件写入操作有关。Python没有石油成员变量的概念,通常在变量前面加单/双下划线来表示私有变量。通常在Python中,以单下划线开始的成员变量称为保护变量,而异双下划线开始的变量称为私有成员变量。 def enterFrame(self): assert not self._enteredFrame if self._capture is not None: self._enteredFrame=self._capture.grab() def exitFrame(self): if self.frame is None: self._enteredFrame=False return if self._enteredFrame==0: self._startTime=time.time() else: timeElapsed=time.time()-self._startTime self._fpsEstimate=self._framesElapsed/timeElapsed self._framesElapsed+=1 if self.previewWindowManager is not None: if self.shouldMirrorPreview: mirroredFrame=numpy.fliplr(self._frame).copy() self.previewWindowManager.show(mirroredFrame) else: self.previewWindowManager.show(self._frame) if self.isWritingImage: cv2.imwrite(self._imageFilename,self._frame) self._imageFilename=None self._videoWriter() self._frame=None self._enteredFrame=False enterFrame()的实现只能(同步)获取一帧,而且会推出从一个通道获取,以便随后能从变量frame中读取。exitFrame()函数可以从当前通道获取图像、估计帧速率、通过窗口管理器显示图像,执行暂停的请求,从而向文件中写入图像。 def writeImage(self,fileneme): self._imageFilename=fileneme def startWritingVideo(self,filename,encoding=cv2.VideoWriter_fourcc('I','4','2','0')): self._videoFilename=filename self._videoEncoding=encoding def stopWritingVideo(self): self._videoFilename=None self._videoEncoding=None self._videoWriter=None def _writeVideoFrame(self): if not self.isWritingVideo: return if self._videoWriter is None: fps=self._capture.get(cv2.CAP_PROP_FPS) if fps==0.0: if self._framesElapsed<20: return else: fps=self._fpsEstimate size=(int(self._capture.get(cv2.CAP_PROP_FRAME_WIDTH)), int(self._capture.get(cv2.CAP_PROP_FRAME_HEIGHT))) self._videoWriter=cv2.VideoWriter( self._videoFilename,self._videoEncoding,fps,size ) self._videoWriter.write(self._frame) writeImage(),startWritingVideo()和stopWritingVideo()是公有函数,简单地记录了文件的写入操作参数,实际写入会推迟到下一下exitFrame()函数。

优秀的个人博客,低调大师

python-opencv学习笔记(三)

Opencv提供了VideoCapture类和VideoWriter类来支持各种格式的视频文件。在到达视频文件末尾之前VideoCapture类可以通过read()函数来获取新的帧,每一帧是一幅BGR格式的图像。可将一幅传递给VideoWriter类的write()函数,该函数会将这幅图像加到VideoWriter类所指向的文件中下面是一个例子,读取MP4文件,并采用YUV颜色编码将其写入另一帧中: import cv2 videoCapture=cv2.VideoCapture('myvid.mp4') fps=videoCapture.get(cv2.CAP_PROP_FPS) size=(int(videoCapture.get(cv2.CAP_PROP_FRAME_WIDTH)), int(videoCapture.get(cv2.CAP_PROP_FRAME_HEIGHT))) videoWriter=cv2.VideoWriter( 'MyOutPut.avi',cv2.VideoWriter_fourcc('I','4','2','0'),fps,size ) success,frame=videoCapture.read() while success: videoWriter.write(frame) success,frame=videoCapture.read() 要注意:必须要为VideoWriter类的构造函数指定视频文件名,这个文件名对应的文件若存在,会被覆盖。也必须指定视频编解码器。编解码器的可能性根据系统不同而不同: cv2.VideoWriter_fourcc(‘I’,‘4’,‘2’,‘0’):该选项是一个未压缩的YUV颜色编码,是4:2:0色度子采集。这种编码兼容性较好,但文件较大,扩展名为.avi cv2.VideoWriter_foucc('P','I','M','I'):该选项是MPEG-1编码类型,扩展名为.avi cv2.VideoWriter_foucc('X','V','I','D'):该选项是MPEG-4编码类型,如果希望得到的视频大小为平均值,推荐使用此选项,文件扩展名.avi cv2.VideoWriter_foucc('T','H','E','O'):该选项Ogg Vorbis,文件扩展名应为.ogv。 cv2.VideoWriter_foucc('F','L','V','I'):该选项是一个Flash视频,文件扩展名应为.flv帧速率和帧大小也应该指定,因为需要从另一个视频复制视频帧,这些属性可以通过VideoCapture类的get()函数得到。 捕获摄像头帧:VideoCapture类可以获得摄像头的帧流。但对摄像头而言,通常不是用视频的文件名来构造VideoCapture类,而是需要传递摄像头的设备索引(device index)。 import cv2 cameraCapture=cv2.VideoCapture(0) fps=30 size=(int (cameraCapture.get(cv2.CAP_PROP_FRAME_WIDTH)), int (cameraCapture.get(cv2.CAP_PROP_FRAME_HEIGHT))) videoWriter=cv2.VideoWriter( 'MyOutPutVid.avi',cv2.VideoWriter_fourcc('I','4','2','0'), fps,size ) success,frame=cameraCapture.read() numFramesRemaining=10*fps-1 while success and numFramesRemaining>0: videoWriter.write(frame) success,frame=cameraCapture.read() numFramesRemaining -=1 cameraCapture.release() 但VideoCapture类的get()方法不能返回摄像头速率的准确值,总是返回0。为了针对摄像头创建合适的VideoWriter类,要么对帧数率做出假设,要么使用计时器来测量,后一种更加好一些。摄像头的数目和顺序系统决定。但OpenCV没有提供任何查询摄像头数目和属性的方法。如果使用无效索引构造了VideoCapture类,就不会得到帧,VideoCapture的read()函数会返回(false,None)。为了不让read()函数从没有正确打开的VideoCapture类中获取数据,可在执行该函数之后使用VideoCa.isOpened方法一个判断,该方法返回一个Boolean值。当需要同步一组摄像头或多头(multihead)摄像头(例如立体摄像头或kinect)时,read()不合适,可用grab()和retrive()代替,可使用以下代码: success0=cameraCaputer0.grad() success1=cameraCapture1.grad() if success0 and success1: frame0=cameraCapture0.retrive() frame1=cameraCapture1.retrive()

优秀的个人博客,低调大师

学习笔记:Docker页面管理平台

Docker Shipyard是什么 ?shipyard是一个开源的docker管理平台,其特性主要包括: 支持节点动态集群,可扩展节点的规模(swarm、etcd方案) 支持镜像管理、容器管理、节点管理等功能 可视化的容器管理和监控管理 在线容器console终端 容器管理 镜像管理 节点管理 容器内部管理 还有很多很好的功能,安装完毕后可以自行探索发现 如何安装? 本文都是A,B节点为模型,A节点是管理节点,B节点只作为node节点 1.在A,B节点上安装docker yum install docker 2.在A,B节点上安装swarm docker pull swarm 3.A节点上安装shipyard curl -s https://shipyard-project.com/deploy | bash -s 注意会用到8080端口,形成页面的管理系统 Username: admin Password: shipyard 4.B节点安装Node curl -sSL https://shipyard-project.com/deploy | ACTION=node DISCOVERY=etcd://A节点IP地址:4001 bash -s 5.测试使用 登陆http://A节点IP地址:8080/ Username: admin Password: shipyard tips: 如果遇到了curl: (35) Peer reports incompatible or unsupported protocol version.的提示请更新下软件就可以解决 命令如下: yum update nss nss-util nspr

优秀的个人博客,低调大师

jquery学习(第三天)

高度和宽度 $(“div”).height();$(“div”).width(); .height()方法和.css(“height”)的区别:返回值不同, .height()方法返回的是 数字类型(20), .css(“height”)返回的是字符串类型(20px), 因此.height()方法常用在参与数学计算的时候 坐标值 $(“div”).offset(); // 获取或设置坐标值 **设置值后变成相对定位**$(“div”).position(); // 获取坐标值 子绝父相 **只能读取不能设置** 固定导航栏(监听scroll) <script type="text/javascript"> $(function () { // 获取顶部 top 的高度值 var topHeight = $(".top").height(); // 监听浏览器的滚动事件 $(window).scroll(function () { var docScrollTop = $(document).scrollTop(); //console.log(docScrollTop); // 判断一下 docScrollTOp 和 topHeight两个大小 // 文档被卷去的高度 大于或等于 top高度的时候 // 让导航栏变成固定定位 if(docScrollTop >= topHeight) { $(".nav").css({ "position": "fixed", "top": 0 }); $(".main").css("margin-top" ,$(".nav").height()); } else { // 让固定导航栏变为默认状态 position: static $(".nav").css({ "position": "static" }); $(".main").css("margin-top" ,0); } }); }); </script> 两侧跟随广告 <script type="text/javascript"> $(function () { $(window).scroll(function () { var docScrollTop = $(document).scrollTop(); //$(".main").css("top", docScrollTop + 80); $(".main").animate({"top" : docScrollTop + 80},30); }); }); </script> 绑定事件 bind 可以绑定一个及以上 中间用空格隔开 可以传两个参数也可以传三个参数 三个参数时中间的值就是函数获取的值$("button").bind("click mouserenter",function(){ alert(111); }); one 单次绑定事件 delegate(委托)绑定方式,可以提高性能 on 事件(就使用它) $("div").on("click","p",function(){ alert(111); }); 第一个参数:触发什么事件 第二个参数:为哪个元素触发事件 第三个参数:处理函数 事件解绑(一一对应) unbind undelegate off 触发事件(提交时校验信息合法性) image.png <script> $(function () { $("form").on("click","#btnSub",function () { var textVal = $("#txtName").val(); if (textVal === "1") { alert("登录成功"); }else { //重新获取焦点 $("#txtName").val("").trigger("focus"); } }); }); </script> click : $(“div”).click(); trigger:触发事件,并且触发浏览器默认行为 triggerHandler:不触发浏览器默认行为 jquery事件对象(重点event=e) event.stopPropagation() //阻止事件冒泡 event.preventDefault(); //阻止默认行为 会做jQuery插件 全局jQuery函数扩展方法 $.log = function() { } //$("li") jQuery扩展方法 $.fn.log = function() { } 引入第三方插件 背景色插件方法 lazyload 插件 jQuery UI 插件 用法很简单: 第一步:引入必要的包 第二步: 实现 安装包管理工具 bower install jquery.lazyloadnmp install jquery-lazyload注意使用nmp的时候需要安装nodejs在pc上 sublime 装插件 sublime 3 第一步: 装上sublime的包管理器package control ctrl+ ~ 上网把 按照package control的那段代码,粘贴一下,然后回车。 第二步:使用Ctrl + shift + p

优秀的个人博客,低调大师

c++ template学习总结3

和往常一样,先来看一段代码: #include <stdexcept> template <typename T, int MAXSIZE> class Stack { private: T elems[MAXSIZE]; // elements int numElems; // current number of elements public: Stack(); // constructor void push(T const&); // push element void pop(); // pop element T top() const; // return top element bool empty() const { // return whether the stack is empty return numElems == 0; } bool full() const { // return whether the stack is full return numElems == MAXSIZE; } }; // constructor template <typename T, int MAXSIZE> Stack<T,MAXSIZE>::Stack () : numElems(0) // start with no elements { // nothing else to do } template <typename T, int MAXSIZE> void Stack<T,MAXSIZE>::push (T const& elem) { if (numElems == MAXSIZE) { throw std::out_of_range("Stack<>::push(): stack is full"); } elems[numElems] = elem; // append element ++numElems; // increment number of elements } template<typename T, int MAXSIZE> void Stack<T,MAXSIZE>::pop () { if (numElems <= 0) { throw std::out_of_range("Stack<>::pop(): empty stack"); } --numElems; // decrement number of elements } template <typename T, int MAXSIZE> T Stack<T,MAXSIZE>::top () const { if (numElems <= 0) { throw std::out_of_range("Stack<>::top(): empty stack"); } return elems[numElems-1]; // return last element } 接下来编写我们的测试函数: #include <iostream> #include <string> #include <cstdlib> #include "stack4.hpp" int main() { try { Stack<int,20> int20Stack; // stack of up to 20 ints Stack<int,40> int40Stack; // stack of up to 40 ints Stack<std::string,40> stringStack; // stack of up to 40 strings // manipulate stack of up to 20 ints int20Stack.push(7); std::cout << int20Stack.top() << std::endl; int20Stack.pop(); // manipulate stack of up to 40 strings stringStack.push("hello"); std::cout << stringStack.top() << std::endl; stringStack.pop(); stringStack.pop(); } catch (std::exception const& ex) { std::cerr << "Exception: " << ex.what() << std::endl; return EXIT_FAILURE; // exit program with ERROR status } } 大家要注意int20Stack和int40Stack是两个不同的类型,他们是不能进行硬是或者显示的转换的。也不能够相互赋值。 你还可以为函数模板定义非型别参数: template <typename T, int VAL> T addValue (T const& x) { return x + VAL; } 当我们想把【函数】和某种操作作为参数传递的时候,就非常有用,比如在使用STL时,你可能有下面的代码: std::transform (source.begin(), source.end(), // start and end of source dest.begin(), // start of destination addValue<int,5>); // operation 有时候我们为了使得编译器推导的时候简单一些,可以使用: std::transform (source.begin(), source.end(), // start and end of source dest.begin(), // start of destination (int(*)(int const&)) addValue<int,5>); // operation 但是我们要注意,非类型模板参数也有自己的局限,通常来说他们只能是常整数,包括枚举,或者指向外部链接的指针。如果我们用浮点数或者class-type objects作为非类型模板参数是错误的: template <double VAT> // ERROR: floating-point values are not double process (double v) // allowed as template parameters { return v * VAT; } template <std::string name> // ERROR: class-type objects are not class MyClass { // allowed as template parameters … }; 由于字串字面常熟是一种采用内部链接的物件,也就是说不通模组中的两个同值的字串字面常数其实是两个不同的东西,所以他们也不能用来作为模板参数: template <char const* name> class MyClass { … }; MyClass<"hello"> x; // ERROR: string literal "hello" not allowed 此外全局指针也是不行的: template <char const* name> class MyClass { … }; char const* s = "hello"; MyClass<s> x; // ERROR: s is pointer to object with internal linkage 但是下面的例子是可以的: template <char const* name> class MyClass { … }; extern char const s[] = "hello"; MyClass<s> x; // OK 在这个例子中,s是一个外部连接的部件。 ============================================================================== 本文转自被遗忘的博客园博客,原文链接:http://www.cnblogs.com/rollenholt/archive/2012/03/08/2384762.html,如需转载请自行联系原作者

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

用户登录
用户注册