c++11新特性:变长参数模板详解

C++(11):变长模板 C++11支持了变长模板参数,可以定义模板函数或模板类,其参数个数是不固定的: template<class T, class... Args> void f(Args... args) 其中Args被称为模板参数包,可以通过class...或typename...来声明 args则代表变长参数集合,称作参数包 #include <iostream> using namespace std; void doF1(int t1) { cout 阅读详情

C++11 变长参数模板

在C++11之前,无论是类模板 还是函数模板,都只能按其指定的样子,接受一组固定数量的模板参数;

这已经大大提升了代码的复用!

在C++11之后,加入了新的表示方 法,允许任意个数、任意类别的模板参数,同时也不需要在定义时将参数的个数固定。更加像”黑魔法“了。

template<typename... Ts> class Magic;

模板类 Magic 的对象,能够接受不受限制个数的 typename 作为模板的形式参数,例如下面的定义:

class Magic<int,
std::vector<int>,
std::map<std::string,
std::vector<int>>> darkMagic;

既然是任意形式,所以个数为 0 的模板参数也是可以的:class Magic<> nothing;。 如果不希望产生的模板参数个数为 0,可以手动的定义至少一个模板参数:

template<typename Require, typename... Args> class Magic;

变长函数参数包

除了在模板参数中能使用…表示不定长模板参数外,函数参数也使用同样的表示法代表不定长参数。

传统 C 中的 printf 函数,虽然也能达成不定个数 的形参的调用,但其并非类别安全。而 C++11 除了能定义类别安全的变长参数函数外,还可以使类似 printf 的函数能自然地处理非自带类别的对象。除了在模板参数中能使用 … 表示不定长模板参数外, 函数参数也使用同样的表示法代表不定长参数,这也就为我们简单编写变长参数函数提供了便捷的手段, 例如:

template<typename... Args> 
void printf(const std::string &str, Args... args);

其中,Args 与 args 分别代表模板与函数的变长参数集合, 称之为参数包 (parameter pack)。参数包必须要和运算符"…"搭配使用。

如何解参数包

长参数模板中,变长参数包无法如同一般参数在类或函数中使用;这个很好理解!

因为在栈中,我们需要先知道函数有多少个参数,才可以入栈,但是我们不知道变长参数有多长,所以需要特殊手法!

sizeof()获得函数参数个数

首先,我们可以使用 sizeof… 来计算参数的个数,:

template<typename... Ts>
void magic(Ts... args) 
{
	std::cout << sizeof...(args) << std::endl;
}

递归模板函数

递归去获得所有参数,是非常容易想到的方法,这种方法不断递归地向函数传递模板参数,进而达到递归遍历所有模板参数的目的。

printf 会不断地递归调用自身:函数参数包 args... 在调用时, 会被模板类别匹配分离为 T value和 Args... args。 直到 args... 变为空参数,则会与简单的 printf(const char *s) 形成匹配,退出递归。

//递归模板函数
template<typename T0>
void printf1(T0 value)
{
	std::cout << value << std::endl;
}
template<typename T, typename... Ts>
void printf1(T value, Ts... args) 
{
	std::cout << value << std::endl;
	printf1(args...);
}
int RecursiveTemplateFunc() 
{
	printf1(1, 2, "123", 1.1);
	return 0;
}

变参模板展开

上面的递归很容易理解,但是比较繁琐,那么还有没有什么好方法呢?

在 C++17 中增加了变参模板展开的支持,于是你可以在一个函数中完 成 printf 的编写:

//变参模板展开
template<typename T0, typename... T>
void printf2(T0 t0, T... t) 
{
	std::cout << t0 << std::endl;
	if constexpr (sizeof...(t) > 0) 
		printf2(t...);
}

结论

模板作为C++中的”黑魔法“般的武器,学起来比较难,但当掌握后,确实非常高级,变长参数模板对我们写模板有很大的帮助!

本文的代码地址: Modern_Cpp_Practice.
代码持续更新,欢迎下载测试,喜欢的给个star!
本系列将长期更新,希望对您有帮助,本文的代码风格参考Google代码风格,希望对您有借鉴!

C++ 新特性 | C++14 常用新特性介绍 本文详细介绍一下C++14的常用新特性。 阅读详情

相关推荐

掌握C++11:现代C++编程特性详解

随着C++11标准的推出,C++语言得到了一次巨大的革新,引入了诸多现代编程语言中的特性。本章将带领读者走进C++11的新世界,理解其带来的关键变化和新特性,这些变化不仅使得C++更为强大,也让编程变得更加便捷和安全。本章的焦点将集中在C++11带来的主要改进上,例如,自动类型推断、右值引用、Lambda表达式、初始化列表等。这些新增特性提供了新的抽象层次和编程范式,显著提高了编程效率和程序性能。

weixin_42513870的博客 972

C++模板元 -- 变长参数模板

变长参数模板 边长参数模板的一般格式是: // 编译递归的终止位置 template <T arg> void foo(T arg) { // do something with arg } // 展开编译表达式 template <typename T, typename ...Args> void foo(T arg, Args... args) { foo(arg, args...); } 给出代码示例,注意都是编译器展开的代码模板,而非运行期。 #include

Erick Lv的笔记 902

C++14编程语言国际标准详解

C++是一种静态类型、编译式、通用编程语言,自1985年第一版标准发布以来,已经经历了多次重大更新。2014年发布的ISO/IEC 14882:2014标准(通常称为C++14)是对C++11标准的进一步完善。C++14旨在提供一个更加成熟、稳定的语言和库,以简化程序员的开发工作,提高代码的性能和可读性。C++14核心特性包括变长参数模板的简化、返回类型自动推导、更灵活的lambda表达式、对并发编程的支持、智能指针的改进、语言和库功能的扩展,以及性能优化和便利特性的增强。

weixin_42462474的博客 924

C++模板编程之变长参数模板

模板:https://zh.cppreference.com/w/cpp/language/templates 变量模板:https://zh.cppreference.com/w/cpp/language/variable_template 类型别名,别名模版:https://zh.cppreference.com/w/cpp/language/type_alias template<class T> struct Alloc { }; template<class T> usin

专注于C/C++/Linux领域创作 3918

环境配置 |Jupyter lab/Jupyter Notebook 安装与设置

ipynb使用Jupyterlab/Jupyter Notebook 来编写程序时的文件,在使用时,可以现转换为标准的.py的python文件。

weixin_44649780的博客 5774

PyQt5 + HFSS:给你的仿真脚本做个专属GUI界面(零基础搭建指南)

本文详细介绍了如何使用PyQt5为HFSS仿真脚本创建专属GUI界面,适合零基础用户快速上手。通过Python二次开发,实现参数可视化调整、进度实时监控等功能,大幅提升团队协作效率。文章涵盖环境配置、界面设计、HFSS集成到打包部署的全流程,是仿真工程师提升工作效率的实用指南。

weixin_42535720的博客 185

c++变长模板参数替代c变长参数

使用c++变长模板参数替代c风格变长参数

weixin_45556596的博客 1031

PaddleOCR在医疗票据识别中的实战:从部署到业务字段提取

本文详细介绍了PaddleOCR在医疗票据识别中的实战应用,重点阐述了其离线部署方案与PP-OCRv3模型选型优势。针对医疗票据敏感数据不出本地的合规要求,文章提供了从环境搭建、模型配置到核心字段提取策略的完整流程,并分享了性能优化与系统集成的实践经验,有效解决了医疗票据自动化录入的难题。

weixin_29271053的博客 238

[C++11] 变长参数模板

说明:C++11 引入了可变参数模板(Variadic Templates)这一功能,也称为变长模板参数。它允许创建可以接受任意数量参数的模板函数或类。args...这个示例展示了可变参数模板的强大功能,可以用来实现类似 printf 这样的可变参数函数。通过递归调用的方式,可以处理任意数量和类型的参数。

wangdsh的博客 1811

[ESP32S3N16R8][LVGL8.3.0][IDF5.2.3]ST7701S RGB屏幕驱动[vscode最详细配置]

ST7701S ESP32S3 基于ESP-IDF5.2.3编写,编程环境为vscode。本教程详细讲述了esp32s3配置st7701s屏幕驱动以及gt911触摸驱动并关联到lvgl8.3.0,使用IDF5.23示例rgb_panel进行测试删除了其里面的屏幕驱动,改为单独编写屏幕和触摸驱动,最后完成了实列。

qq_44022379的博客 2608

华为手机连接Win11失败?内核隔离与驱动签名冲突的终极解决指南

在Windows操作系统中,驱动程序是硬件与系统通信的桥梁,其数字签名机制是保障系统内核安全的核心防线。基于虚拟化的安全技术通过强制验证驱动签名,能有效隔离恶意代码,提升系统抵御高级威胁的能力。然而,严格的签名策略有时会与部分硬件驱动产生兼容性问题,导致设备无法识别,直接影响文件传输、应用调试等核心工作流。本文聚焦于华为手机在开启Windows 11内核隔离功能时出现的连接故障,深入剖析驱动签名验证与Hypervisor保护的代码完整性原理,并提供从驱动更新、策略调整到无线替代方案的完整解决路径,帮助用户在

weixin_31309419的博客 357

C++11新特性之变长参数模板详解

本文主要介绍了C++11变长参数模板,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 目录 C++11 变长参数模板 变长函数参数包 如何解参数包 sizeof()获得函数参数个数 递归模板函数 变参模板展开 结论 C++11 变长参数模板 在C++11之前,无论是类模板 还是函数模板,都只能按其指定的样子,接受一组固定数量的模板参数; 这已经大大提升了代码的复用! 在C++11之后,加入了新..

zhang_xiaoqiang的博客 1070

YOLOv11在视频流中的时序建模改进-(加入ConvLSTM或Transformer捕捉帧间关联)

本文提出了一种结合ConvLSTM和Transformer的改进YOLOv11算法,用于增强视频目标检测的时序建模能力。针对视频检测中运动模糊、遮挡等挑战,研究分析了ConvLSTM的局部时空特征建模和Transformer的全局注意力机制之间的互补性。通过数学公式详细阐述了ConvLSTM的门控机制和Transformer的自注意力计算原理,并提出分层融合策略:底层使用ConvLSTM处理高分辨率特征捕捉局部运动,高层应用Transformer建立全局时空关联。改进方案在YOLOv11架构中插入时序增强模

本博客聚焦 YOLOv11 全流程落地,涵盖架构优化、数据集处理、训练技巧与多场景部署,兼及国产数据库、Java 开发与 AI 模型应用,内容兼顾理论与工程实践,为开发者提供系统干货,助力高效提升技术能力。 680

c++ 常用新特性总结【c++11】,【c++14】,【c++17】,【c++20】

一文总结了c++常见的新特性,在c++推出的新特性中,c++11无疑是最具影响力的,其次是c++17与c++14。

Ray 6228

用生成式AI自动生成测试用例的完整教程

本文旨在帮助测试工程师、开发人员快速掌握“生成式AI自动生成测试用例”的核心技术,覆盖从概念理解、工具选择到实战落地的全流程。无论是Web应用、API接口还是移动端功能测试,你都能找到可复用的方法。本文将按照“概念→原理→实战→避坑”的逻辑展开:先通过生活案例理解生成式AI如何生成测试用例,再拆解核心算法原理,接着用Python代码演示完整生成流程,最后分享实际应用中的优化技巧和未来趋势。生成式AI:能“创造内容”的AI模型(如ChatGPT、CodeLlama),像会写作文的智能笔。测试用例。

AIGC应用创新大全的博客 1581

RedCap:一种通信技术的概述

总结起来,RedCap是一种基于数据包交换的通信技术,它提供了一种高效、可靠的数据传输机制。通过使用RedCap,我们可以轻松地发送和接收数据包,并确保数据的完整性和正确性。在上面的示例中,我们首先导入了RedCap库,并创建了一个RedCap实例。然后,我们定义了目标地址和源地址,并创建了一个数据包,其中包含了目标地址、源地址和要发送的数据。本文将介绍RedCap的基本原理和使用方法,并提供一些相关的源代码示例。RedCap还提供了其他一些功能,如数据包的重传机制、流量控制和拥塞控制等。

YgjWeb的博客 900

C++11 & C++14 & C++17新特性

C++11:C++11包括大量的新特性:包括lambda表达式,类型推导关键字auto、decltype,和模板的大量改进。 新的关键字 auto C++11中引入auto第一种作用是为了自动类型推导 auto的自动类型推导,用于从初始化表达式中推断出变量的数据类型。通过auto的自动类型推导,可以大大简化我们的编程工作 auto实际上实在编译时对变量进行了类型推导,所以不会对程序的运行...

LANGZI7758521的专栏 7684

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

C++11新特性

什么是C++11 C++11是曾经被叫做C++0x,是对目前C++语言的扩展和修正,C++11不仅包含核心语言的新机能,而且扩展了C++的标准程序库(STL),并入了大部分的C++ Technical Report 1(TR1)程序库(数学的特殊函数除外)。 C++11包括大量的新特性:包括lambda表达式,类型推导关键字auto、decltype,和模板的大量改进。 本文将对C++11的以上新特性进行简单的讲解,以便大家能够快速了解到C++11对C++的易用性方面起到的巨大作用。 C++11

8078

ssm框架搭建

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

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

C++11新特性总结

C++11引入了许多新特性,如auto关键字实现自动类型推导,nullptr代替NULL,智能指针如unique_ptr和shared_ptr更安全地管理内存,lambda表达式简化函数对象的书写,委托构造函数和默认删除函数增强了类的构造与析构控制,移动语义提高了效率,变长参数模板variadic templates支持可变数量的参数类型。这些特性大大提高了C++的易用性和性能,并使得代码更简洁、安全、高效。

白云之道 1328

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

C++ 11/14/17 新特性

c++新特性 nullptr 空指针 防止隐式的类型转换 NULL 和 0 constexpr 常量表达式 constexpr函数可以使用递归 constexpr int fibonacci(const int n) { return n == 1 || n == 2 ? 1 : fibonacci(n-1)+fibonacci(n-2); } 并且从c++14开始,constexpr函数内可以使用局部变量,循环,分支等简单语句 if/switch 语句初始化 c++17让我们可以在if或swit

heaven5heep blog 385

C++98和C++11的特性和改进

需要注意的是,相较于 C++11、C++14 和 C++17,C++98 的新特性相对较少,C++11 引入的新特性更加丰富和强大。类型推断:C++11 引入了 decltype 关键字和更加灵活的模板类型推导规则,提高了 C++ 中类型推断的能力。新的标准库组件:C++11 引入了新的标准库组件,如正则表达式库、元组库、随机数库等,增强了 C++ 标准库的功能。总的来说,C++11 相较于 C++98 引入了许多重要的新特性和改进,使得 C++ 编程更加方便、灵活和高效,提高了代码的质量和效率。

m0_60352504的博客 1834

30分钟了解C++11新特性

什么是C++11C++11是曾经被叫做C++0x,是对目前C++语言的扩展和修正,C++11不仅包含核心语言的新机能,而且扩展了C++的标准程序库(STL),并入了大部分的C++ Technical Report 1(TR1)程序库(数学的特殊函数除外)。C++11包括大量的新特性:包括lambda表达式,类型推导关键字auto、decltype,和模板的大量改进。本文将对C++11的以上新特性进...

imJaron的博客 368

【C++面试知识】C++11新特性

1.新的keyword (1)auto 自动类型推导: auto a; // 错误,auto是通过初始化表达式进行类型推导,假设没有初始化表达式,就无法确定a的类型 auto i = 1; auto d = 1.0; auto str = "Hello World"; auto ch = 'A'; auto func = less<int>(); vector<int&g...

a15920804211的博客 5402

c++11& C++14新特性

阅读目录 Lambda函数 constexpr 类型推导 C++11:C++11包括大量的新特性:包括lambda表达式,类型推导关键字auto、decltype,和模板的大量改进。 新的关键字 auto C++11中引入auto第一种作用是为了自动类型推导 auto的自动类型推导,用于从初始化表达式中推断出变量的数据类型。通过auto的自动类型推导,可以大大简化我们的编程工作 a...

jaccen的专栏 530
上一篇: 现代C++实战100练:初始化列表
下一篇: 一文搞定json解析和封装问题,手把手带你学习CJSON开源代码
CodeBowl
博客等级 码龄5年 7664粉丝 67原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值