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

ubuntu下yolov5 tensorrt模型部署

文章目录

  • ubuntu下yolov5 tensorrt模型部署
    • 一、Ubuntu18.04环境配置
    • 1.1 安装工具链和opencv
    • 1.2 安装Nvidia相关库
      • 1.2.1 安装Nvidia显卡驱动
      • 1.2.2 安装 cuda11.3
      • 1.2.3 安装 cudnn8.2
      • 1.2.4 下载 tensorrt8.4.2.4
      • 1.2.5 下载仓库TensorRT-Alpha并设置
    • 二、从yolov5源码中导出onnx文件
    • 三、利用tensorrt编译onnx模型
    • 四、编译执行yolov5-tensorrt工程
    • 五、结束语

ubuntu下yolov5 tensorrt模型部署

  • YOLOv5的创新性:相比于之前的目标检测算法,YOLOv5在多个方面进行了创新和优化。首先,它在网络结构上采用了轻量级的设计,使用了CSPDarknet53作为骨干网络,减少了计算量和参数量,提高了算法的实时性和效率。其次,YOLOv5引入了蒸馏学习策略,使用教师模型指导学生模型进行学习,提高了模型的性能和泛化能力。此外,YOLOv5还采用了多尺度特征融合策略,使得模型能够更好地捕捉到不同尺度的目标特征。另外,YOLOv5还改进了损失函数的设计,采用GIOU和COCO等损失函数,提高了模型的准确性。
  • YOLOv5对工业界的影响:YOLOv5的推出对工业界产生了广泛的影响。首先,它被广泛应用于智能驾驶、安防监控、机器人视觉等场景中,为工业界提供了更准确、高效和可靠的目标检测工具。其次,YOLOv5的推出加速了目标检测技术的发展和应用,促进了计算机视觉领域的进步。此外,YOLOv5的开源也为工业界提供了更多的参考和选择,推动了深度学习算法的发展和完善。
  • YOLOv5的优点:YOLOv5具有多个优点。首先,它具有高效性,能够在短时间内处理大量的图像和视频数据。其次,YOLOv5具有准确性,能够准确地检测到目标物体并对其进行分类和定位。此外,YOLOv5还具有实时性,能够实时地输出检测结果和处理速度,使得它能够适用于各种实际应用场景中。另外,YOLOv5还具有易用性,其简单的接口和易懂的文档使得开发者可以轻松上手并开发出高质量的目标检测程序。

本文提供yolov5-tensorrt加速方法。
有源码!有源码!有源码! 不要慌,哈哈哈。
在这里插入图片描述
下图右边是yolov5s部署之后,tensorrt部署效果,和python推理结果一致。
在这里插入图片描述

yolov5s : Offical( left ) vs Ours( right )

一、Ubuntu18.04环境配置

如果您对tensorrt不是很熟悉,请务必保持下面库版本一致。
请注意: Linux系统安装以下库,务必去进入系统bios下,关闭安全启动(设置 secure boot 为 disable)

1.1 安装工具链和opencv

sudo apt-get update 
sudo apt-get install build-essential 
sudo apt-get install git
sudo apt-get install gdb
sudo apt-get install cmake
sudo apt-get install libopencv-dev  
# pkg-config --modversion opencv

1.2 安装Nvidia相关库

注:Nvidia相关网站需要注册账号。

1.2.1 安装Nvidia显卡驱动

ubuntu-drivers devices
sudo add-apt-repository ppa:graphics-drivers/ppa
sudo apt update
sudo apt install nvidia-driver-470-server # for ubuntu18.04
nvidia-smi

1.2.2 安装 cuda11.3

  • 进入链接: https://developer.nvidia.com/cuda-toolkit-archive
  • 选择:CUDA Toolkit 11.3.0(April 2021)
  • 选择:[Linux] -> [x86_64] -> [Ubuntu] -> [18.04] -> [runfile(local)]

    在网页你能看到下面安装命令,我这里已经拷贝下来:
wget https://developer.download.nvidia.com/compute/cuda/11.3.0/local_installers/cuda_11.3.0_465.19.01_linux.run
sudo sh cuda_11.3.0_465.19.01_linux.run

cuda的安装过程中,需要你在bash窗口手动作一些选择,这里选择如下:

  • select:[continue] -> [accept] -> 接着按下回车键取消Driver和465.19.01这个选项,如下图(it is important!) -> [Install]

    在这里插入图片描述
    bash窗口提示如下表示安装完成
#===========
#= Summary =
#===========#Driver:   Not Selected
#Toolkit:  Installed in /usr/local/cuda-11.3/
#......

把cuda添加到环境变量:

vim ~/.bashrc

把下面拷贝到 .bashrc里面

# cuda v11.3
export PATH=/usr/local/cuda-11.3/bin${PATH:+:${PATH}}
export LD_LIBRARY_PATH=/usr/local/cuda-11.3/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
export CUDA_HOME=/usr/local/cuda-11.3

刷新环境变量和验证

source ~/.bashrc
nvcc -V

bash窗口打印如下信息表示cuda11.3安装正常

nvcc: NVIDIA (R) Cuda compiler driver<br>
Copyright (c) 2005-2021 NVIDIA Corporation<br>
Built on Sun_Mar_21_19:15:46_PDT_2021<br>
Cuda compilation tools, release 11.3, V11.3.58<br>
Build cuda_11.3.r11.3/compiler.29745058_0<br>

1.2.3 安装 cudnn8.2

  • 进入网站:https://developer.nvidia.com/rdp/cudnn-archive
  • 选择: Download cuDNN v8.2.0 (April 23rd, 2021), for CUDA 11.x
  • 选择: cuDNN Library for Linux (x86_64)
  • 你将会下载这个压缩包: “cudnn-11.3-linux-x64-v8.2.0.53.tgz”
# 解压
tar -zxvf cudnn-11.3-linux-x64-v8.2.0.53.tgz

将cudnn的头文件和lib拷贝到cuda11.3的安装目录下:

sudo cp cuda/include/cudnn.h /usr/local/cuda/include/
sudo cp cuda/lib64/libcudnn* /usr/local/cuda/lib64/
sudo chmod a+r /usr/local/cuda/include/cudnn.h
sudo chmod a+r /usr/local/cuda/lib64/libcudnn*

1.2.4 下载 tensorrt8.4.2.4

本教程中,tensorrt只需要下载\、解压即可,不需要安装。

  • 进入网站: https://developer.nvidia.cn/nvidia-tensorrt-8x-download
  • 把这个打勾: I Agree To the Terms of the NVIDIA TensorRT License Agreement
  • 选择: TensorRT 8.4 GA Update 1
  • 选择: TensorRT 8.4 GA Update 1 for Linux x86_64 and CUDA 11.0, 11.1, 11.2, 11.3, 11.4, 11.5, 11.6 and 11.7 TAR Package
  • 你将会下载这个压缩包: “TensorRT-8.4.2.4.Linux.x86_64-gnu.cuda-11.6.cudnn8.4.tar.gz”
# 解压
tar -zxvf TensorRT-8.4.2.4.Linux.x86_64-gnu.cuda-11.6.cudnn8.4.tar.gz
# 快速验证一下tensorrt+cuda+cudnn是否安装正常
cd TensorRT-8.4.2.4/samples/sampleMNIST
make
cd ../../bin/

导出tensorrt环境变量(it is important!),注:将LD_LIBRARY_PATH:后面的路径换成你自己的!后续编译onnx模型的时候也需要执行下面第一行命令

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/xxx/temp/TensorRT-8.4.2.4/lib
./sample_mnist

bash窗口打印类似如下图的手写数字识别表明cuda+cudnn+tensorrt安装正常
在这里插入图片描述

1.2.5 下载仓库TensorRT-Alpha并设置

git clone https://github.com/FeiYull/tensorrt-alpha

设置您自己TensorRT根目录:

git clone https://github.com/FeiYull/tensorrt-alpha
cd tensorrt-alpha/cmake
vim common.cmake
# 在文件common.cmake中的第20行中,设置成你自己的目录,别和我设置一样的路径eg:
# set(TensorRT_ROOT /root/TensorRT-8.4.2.4)

二、从yolov5源码中导出onnx文件

可以直接从网盘下载onnx文件[weiyun]:weiyun or google driver ,你也可以自己下载仓库,然后按照下面指令手动导出onnx文件:

# 下载yolov5源码
git clone https://github.com/ultralytics/yolov5

切换版本为yolov5.7.0

git checkout v7.0

安装 yolov5环境

pip install -r requirements.txt

用以下指令导出onnx模型文件,640表示模型的输入分辨率为:640X640,1280同理表示:1280X1280。建议使用640对应的小模型。

# 640
python export.py --weights=yolov5n.pt  --dynamic --include=onnx 
python export.py --weights=yolov5s.pt  --dynamic --include=onnx
python export.py --weights=yolov5m.pt  --dynamic --include=onnx
python export.py --weights=yolov5l.pt  --dynamic --include=onnx
python export.py --weights=yolov5x.pt  --dynamic --include=onnx
# 1280
python export.py --weights=yolov5n6.pt  --dynamic --include=onnx
python export.py --weights=yolov5s6.pt  --dynamic --include=onnx
python export.py --weights=yolov5m6.pt  --dynamic --include=onnx
python export.py --weights=yolov5l6.pt  --dynamic --include=onnx
python export.py --weights=yolov5x6.pt  --dynamic --include=onnx

三、利用tensorrt编译onnx模型

将你的onnx模型放到这个路径:tensorrt-alpha/data/yolov5

cd tensorrt-alpha/data/yolov5
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/TensorRT-8.4.2.4/lib

编译onnx模型指令,640表示模型的输入分辨率为:640X640,1280同理表示:1280X1280。注意:编译onnx格式的模型会得到例如xxxx.trt格式的文件,下文推理要用到。

# 640
../../../../TensorRT-8.4.2.4/bin/trtexec   --onnx=yolov5n.onnx   --saveEngine=yolov5n.trt  --buildOnly --minShapes=images:1x3x640x640 --optShapes=images:4x3x640x640 --maxShapes=images:8x3x640x640
../../../../TensorRT-8.4.2.4/bin/trtexec   --onnx=yolov5s.onnx   --saveEngine=yolov5s.trt   --buildOnly --minShapes=images:1x3x640x640 --optShapes=images:4x3x640x640 --maxShapes=images:8x3x640x640
../../../../TensorRT-8.4.2.4/bin/trtexec   --onnx=yolov5m.onnx   --saveEngine=yolov5m.trt  --buildOnly --minShapes=images:1x3x640x640 --optShapes=images:4x3x640x640 --maxShapes=images:8x3x640x640
../../../../TensorRT-8.4.2.4/bin/trtexec   --onnx=yolov5l.onnx   --saveEngine=yolov5l.trt  --buildOnly --minShapes=images:1x3x640x640 --optShapes=images:4x3x640x640 --maxShapes=images:8x3x640x640
../../../../TensorRT-8.4.2.4/bin/trtexec   --onnx=yolov5x.onnx   --saveEngine=yolov5x.trt  --buildOnly --minShapes=images:1x3x640x640 --optShapes=images:4x3x640x640 --maxShapes=images:8x3x640x640
# 1280
../../../../TensorRT-8.4.2.4/bin/trtexec   --onnx=yolov5n6.onnx   --saveEngine=yolov5n6.trt  --buildOnly --minShapes=images:1x3x1280x1280 --optShapes=images:4x3x1280x1280 --maxShapes=images:8x3x1280x1280
../../../../TensorRT-8.4.2.4/bin/trtexec   --onnx=yolov5s6.onnx   --saveEngine=yolov5s6.trt  --buildOnly --minShapes=images:1x3x1280x1280 --optShapes=images:4x3x1280x1280 --maxShapes=images:8x3x1280x1280

四、编译执行yolov5-tensorrt工程

使用命令行编译下代码

git clone https://github.com/FeiYull/tensorrt-alpha
cd tensorrt-alpha/yolov5
mkdir build
cd build
cmake ..
make -j10

按照需求执行推理,支持推理一张图片、在线推理视频文件,或者在线从摄像头获取视频流并推理。

# 640
# infer an image
./app_yolov5  --version=v570 --model=../../data/yolov5/yolov5n.trt   --size=640  --batch_size=1  --img=../../data/6406401.jpg   --show --savePath=../
# infer video
./app_yolov5  --version=v570 --model=../../data/yolov5/yolov5n.trt   --size=640  --batch_size=8  --video=../../data/people.mp4  --show 
# infer web camera
./app_yolov5  --version=v570 --model=../../data/yolov5/yolov5n.trt   --size=640  --batch_size=2  --show  --cam_id=0# 1280
./app_yolov5  --version=v570 --model=../../data/yolov5/yolov5s6.trt  --size=1280 --batch_size=1 --img=../../data/6406401.jpg   --show --savePath

例如:以下是yolov5推理视频流效果。
在这里插入图片描述

五、结束语

都看到这里了,觉得可以请点赞收藏,有条件的去仓库点个star,仓库:https://github.com/FeiYull/tensorrt-alpha
在这里插入图片描述

相关文章:

ubuntu下yolov5 tensorrt模型部署

文章目录 ubuntu下yolov5 tensorrt模型部署一、Ubuntu18.04环境配置1.1 安装工具链和opencv1.2 安装Nvidia相关库1.2.1 安装Nvidia显卡驱动1.2.2 安装 cuda11.31.2.3 安装 cudnn8.21.2.4 下载 tensorrt8.4.2.41.2.5 下载仓库TensorRT-Alpha并设置 二、从yolov5源码中导出onnx文…...

windows Vscode 连接 虚拟机,超详细,含免密免ip配置 以 linux 虚拟机为例

我们这里使用 ssh 进行连接&#xff0c;不了解 ssh 的也没关系&#xff0c;感兴趣的可以自己了解一下。 我的虚拟机是 Ubuntu20.04&#xff0c;如果出现与 Centos 不一样的操作可以自行替换。 &#xff08;应该不会有&#xff1f;&#xff1f;&#xff09; 一 . 登录虚拟机~&a…...

【Unity】VR基础开发2项目准备-VR基本场景构建(OpenXR方向)

【文字内容】 稍等一会儿,编辑器界面就出现了。有可能你的界面布局会有所不同,可以在右上角点击布局,选择Tall,布局切换后在来到左边窗口的左上角,将Game选项卡拖放到下方Dock,这样就可以得到和我一样的布局了。 简单介绍一下。 场景面板是对游戏进行可视化编辑的地方…...

git checkout 命令

一、拉取更新某个分支中某个文件/文件夹 git checkout 分支名 文件路径 git checkout temporary src/components/tools/UserMenu.vue 二、回退某个文件到前一个提交 git checkout HEAD^ 文件路径 git checkout HEAD^ src/components/tools/UserMenu.vue 如果你要回退到…...

二.镜头知识之镜头总长,法兰距,安装接口

二.镜头知识之镜头总长&#xff0c;法兰距&#xff0c;安装接口 文章目录 二.镜头知识之镜头总长&#xff0c;法兰距&#xff0c;安装接口2.1 线激光模组镜头的FBL 与 TTL(Total Track Length) 镜头总长2.2 相机法兰距2.3 线激光模组镜头的TTL 以及 From Barrel bottom to imag…...

Android studio控制台 输出乱码解决方法

在AS的安装目录&#xff0c;找到 studio64.exe.vmoptions 文件&#xff0c; 用编辑器打开文件&#xff0c;在最后面加上下面的代码&#xff1a; -Defile.encodingUTF-8然后 重启AS。 注意&#xff1a; 下面两种方式也能打开studio64.exe.vmoptions 文件&#xff0c;但是需要确…...

Hermes - 指尖上的智慧:自定义问答系统的崭新世界

在希腊神话中&#xff0c;有一位智慧与消息的传递者神祇&#xff0c;他就是赫尔墨斯&#xff08;Hermes&#xff09;。赫尔墨斯是奥林匹斯众神中的一员&#xff0c;传说他是乌尔阿努斯&#xff08;Uranus&#xff09;和莫伊拉&#xff08;Maia&#xff09;的儿子&#xff0c;同…...

机器学习笔记 - 使用3D卷积神经网络进行视频分类

1、导入相应的库 3D CNN 使用三维滤波器来执行卷积。内核能够在三个方向上滑动,而在 2D CNN 中它可以在二维上滑动。 首先安装并导入必要的库,用于处理ZIP文件内容的Remotezip 、用于使用进度条的tqdm 、用于处理视频文件的OpenCV 、用于执行更复杂的张量操作的einop…...

在Unity中挂载C#脚本的三种方法

第一种 ①在Project&#xff08;工程&#xff09;窗口的某个文件夹中&#xff08;也可以选择新建在Assets&#xff08;资源根目录&#xff09;中&#xff09;&#xff0c;然后单击鼠标右键&#xff0c;选择Create->C# Script 注意&#xff1a;扩展名在Unity编辑器中是隐藏…...

vue elementui的select组件实现滑到底部分页请求后端接口

vue elementui的select组件实现滑到底部分页请求后端接口 1.实现效果2.实现原理 1.实现效果 老规矩&#xff0c;直接上最后的实现效果 2.实现原理 直接上代码 <el-form-item class"diagmosisItem" label"诊断" v-scroll"handleScroll">…...

【Java 进阶篇】JavaScript电灯开关案例:从原理到实现

JavaScript是一门强大的编程语言&#xff0c;它可以用来创建各种交互式网页应用。在这篇博客中&#xff0c;我们将通过一个简单的电灯开关案例来深入了解JavaScript的基础概念&#xff0c;包括HTML、CSS和JavaScript的结合使用。我们将从头开始构建这个案例&#xff0c;逐步引入…...

并发、并行、同步、异步、阻塞、非阻塞

一、多核、多cpu &#xff08;一&#xff09;多核 Multicore 核是CPU最重要的部分。负责运算。核包括控制单元、运算单元、寄存器等单元。 多核就是指单个CPU中有多个核。 &#xff08;二&#xff09;多cpu Multiprocessor 多cpu就是一个系统拥有多个CPU。每个CPU可能有单个核…...

C语言:冒泡排序

C语言 基础开发----目录 冒泡排序 1. 原理 对一个有n个数据的数组进行遍历&#xff0c;依次对相邻两个数据进行比较大小&#xff0c;若大的数据在前面则交换位置&#xff08;升序&#xff09;&#xff0c;完成一次遍历后数组中最大的数据到了数组的末尾位置&#xff0c;就象水…...

Android 内容提供者和内容观察者:数据共享和实时更新的完美组合

任务要求 一个作为ContentProvider提供联系人数据另一个作为Observer监听联系人数据的变化&#xff1a; 1、创建ContactProvider项目&#xff1b; 2、在ContactProvider项目中用Sqlite数据库实现联系人的读写功能&#xff1b; 3、在ContactProvider项目中通过ContentProvid…...

六、K8S之StatefulSet

StatefulSet 一、概念 和Deployment一样StatefulSet也是中一种可以帮助我们部署和扩展Pod的控制器&#xff0c;使用Deployment时多数时候不需要在意Pod的调度方式。如果需要关心Pod的部署顺序、对应持久化存储或者要求Pod拥有固定的网络标识时&#xff0c;就需要StatefulSet控…...

基于微服务+Java+Spring Cloud开发的建筑工地智慧平台源码 云平台多端项目源码

建筑工地智慧平台源码&#xff0c;施工管理端、项目监管端、数据大屏端、移动APP端全套源码 技术架构&#xff1a;微服务JavaSpring Cloud VueUniApp MySql自主版权实际应用案例演示 建筑工地智慧平台已应用于线上巡查、质量管理、实名制管理、危大工程管理、运渣车管理、绿色…...

微信小程序异常:navigateTo:fail can not navigateTo a tabbar page

场景还原 微信小程序利用路径wx.navigateTo跳转界面时发送异常 跳转代码 showDetail(e){// 获取图片绑定的ID编号let id e.currentTarget.dataset.id;// 指定编号查询 携带参数到详情界面 wx.navigateTo({url: /pages/details/details?id id,})}异常代码 WAServiceMain…...

智慧公厕高精尖技术揭秘,让卫生管理更智能、更舒适

随着科技的飞速发展&#xff0c;智慧公厕正逐渐走进人们的生活。借助物联网、互联网、云计算、大数据、人工智能、自动化控制等技术的应用&#xff0c;智慧公厕将卫生管理提升到一个全新的水平&#xff0c;为公众打造了清洁舒适的使用环境。本文以智慧公厕源头厂家广州中期科技…...

Spring Cloud的革新:服务网格和云原生整合

文章目录 介绍Spring Cloud服务网格的兴起Spring Cloud与Service Mesh的整合1. 服务发现2. 负载均衡3. 故障处理4. 安全性 云原生整合结论 &#x1f389;欢迎来到架构设计专栏~Spring Cloud的革新&#xff1a;服务网格和云原生整合 ☆* o(≧▽≦)o *☆嗨~我是IT陈寒&#x1f37…...

EfficientDet: Scalable and Efficient Object Detection

CVPR2020 V7 Mon, 27 Jul 2020 引用量&#xff1a;243 机构&#xff1a;Google 贡献&#xff1a;1>提出了多尺度融合网络BiFPN 2>对backbone、feature network、box/class prediction network and resolution进行复合放缩&#xff0c;有着不同的…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

RocketMQ延迟消息机制

两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数&#xff0c;对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后&#xf…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

OPENCV形态学基础之二腐蚀

一.腐蚀的原理 (图1) 数学表达式&#xff1a;dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一&#xff0c;腐蚀跟膨胀属于反向操作&#xff0c;膨胀是把图像图像变大&#xff0c;而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...

初探Service服务发现机制

1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能&#xff1a;服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源&#xf…...

QT3D学习笔记——圆台、圆锥

类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体&#xff08;对象或容器&#xff09;QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质&#xff08;定义颜色、反光等&#xff09;QFirstPersonC…...

Web中间件--tomcat学习

Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机&#xff0c;它可以执行Java字节码。Java虚拟机是Java平台的一部分&#xff0c;Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...

代码规范和架构【立芯理论一】(2025.06.08)

1、代码规范的目标 代码简洁精炼、美观&#xff0c;可持续性好高效率高复用&#xff0c;可移植性好高内聚&#xff0c;低耦合没有冗余规范性&#xff0c;代码有规可循&#xff0c;可以看出自己当时的思考过程特殊排版&#xff0c;特殊语法&#xff0c;特殊指令&#xff0c;必须…...

省略号和可变参数模板

本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...