C++标准模板(STL)- 变参数函数

变参数函数 

变参数函数是接收可变数量参数的函数(例如 std::printf )。

为声明变参数函数,要以省略号为最后的形参,例如 int printf(const char* format, ...); 。语法上的额外细节、自动参数转换及替用项见变参数。

为从函数体内访问可变参数,标准库提供下列库设施:

定义于头文件 <cstdarg>

va_start

启用对可变函数实参的访问
(宏函数)

va_arg

访问下一个可变函数实参
(宏函数)

va_copy

(C++11)

制造可变函数实参的副本
(宏函数)

va_end

结束对可变函数实参的遍历
(宏函数)

va_list

保有 va_start、va_arg、va_end 和 va_copy 所需的信息

启用对可变函数实参的访问

va_start

void va_start( std::va_list ap, parm_n );

va_start 宏允许访问后随具名参数 parm_n 的可变参数。

va_start 应当在任何对 va_arg 的调用前,以到合法 std::va_list 对象 ap 的实例调用。

parm_n 声明为有引用类型,或与来自默认参数提升的结果不兼容的类型,则行为未定义。

参数

ap-std::va_list 类型的实例
parm_n-首个可变参数前紧接的具名参数

展开值

(无)

注意

要求 va_start 支持带重载的 operator&parm_n

访问下一个可变函数实参

va_arg

T va_arg( std::va_list ap, T );

va_arg 宏展开成对应来自 std::va_list ap 的下个参数的 T 类型表达式。

在调用 va_arg 前, ap 必须为到 va_start 或 va_copy 的调用所初始化,中间不能夹带 va_end 的调用。 va_arg 宏的每次调用都修改 ap ,令它指向下个可变参数。

ap 中的下个参数类型(提升后)与 T 不兼容,则行为未定义,除非:

  • 一个类型是有符号整数类型,而另一类型是无符号整数类型,且值能用两个类型表示;或
  • 一个类型是指向 void 的指针,而另一类型是指向字符类型( char 、 signed char 或 unsigned char )的指针。

若在 ap 中无更多参数时调用 va_arg ,则行为未定义。

参数

ap-std::va_list 类型的实例
T-ap 中下个参数的类型

展开值

ap 中的下个可变参数

制造可变函数实参的副本

va_copy

void va_copy( std::va_list dest, std::va_list src );

(C++11 起)

va_copy 宏复制 srcdest

va_end 应当在函数返回前或任何 dest 的后继重初始化(通过对 va_start 或 va_copy 的调用)前对 dest 调用。

参数

dest-要初始化的 std::va_list 类型实例
src-将用于初始化 dest 的源 std::va_list

展开值

(无)

结束对可变函数实参的遍历

va_end

void va_end( va_list ap );

va_end 宏进行对为 va_start 或 va_copy 所初始化的 ap 对象的清理。 va_end 可以修改 ap 并令它不再可用。

若无对应的对 va_start 或 va_copy 的调用,或若 va_end 未在调用 va_start 或 va_copy 的函数返回前调用,则行为未定义。

参数

ap-要清理的 va_list 类型实例

展开值

(无)

保有 va_start、va_arg、va_end 和 va_copy 所需的信 

std::va_list

va_list 是适用于保有宏 va_start 、 va_arg 及 va_end 所需信息的完整对象类型。

若创建 va_list 实例,并传递给另一函数,且通过 va_arg 在该函数中使用,则调用方函数的任何后继使用必须前附对 va_end 的调用。

传递指向 va_list 对象的指针给另一函数,并在函数返回后使用该对象是合法的。

调用示例

#include <iostream>
#include <cstdarg>
#include <cmath>
#include <typeinfo>struct Cell
{int x;int y;
};std::ostream &operator<<(std::ostream &os, const Cell &cell)
{os << "{" << cell.x << "," << cell.y << "}";return os;
}double sample_stddev(const int count, ...)
{double sum = 0;std::va_list args1;va_start(args1, count);std::va_list args2;va_copy(args2, args1);for (int i = 0; i < count; ++i){double num = va_arg(args1, double);sum += num;}va_end(args1);double mean = sum / count;double sum_sq_diff = 0;for (int i = 0; i < count; ++i){double num = va_arg(args2, double);sum_sq_diff += (num - mean) * (num - mean);}va_end(args2);return std::sqrt(sum_sq_diff / count);
}void simple_printf(const char* fmt...)
{va_list args;va_start(args, fmt);while (*fmt != '\0'){if (*fmt == 'd'){int i = va_arg(args, int);std::cout << typeid(i).name() << " : " << i << std::endl;}else if (*fmt == 'c'){// 注意自动转换到整数类型int c = va_arg(args, int);std::cout << typeid(c).name() << " : " << static_cast<char>(c) << std::endl;}else if (*fmt == 'f'){double d = va_arg(args, double);std::cout << typeid(d).name() << " : " << d << std::endl;}++fmt;}va_end(args);
}void Cell_printf(const int count, ...)
{std::va_list args1;va_start(args1, count);for (int i = 0; i < count; ++i){Cell cell = va_arg(args1, Cell);std::cout << typeid(cell).name() << " : " << cell << std::endl;}va_end(args1);
}int main()
{simple_printf("dcff", 3, 'a', 1.999, 42.5);std::cout << sample_stddev(4, 25.0, 27.3, 26.9, 25.7) << std::endl;Cell_printf(3, Cell{101, 101}, Cell{102, 102}, Cell{103, 103});return 0;
}

输出

i : 3
i : a
d : 1.999
d : 42.5
0.920258
4Cell : {101,101}
4Cell : {102,102}
4Cell : {103,103}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

L9110S电机控制模块

1.L9110s控制小车前进后退左右 接通VCC&#xff0c;GND 模块电源指示灯亮&#xff0c; 以下资料来源官方&#xff0c;但是仍需我们调制 &#xff08;前进&#xff09;&#xff1a; L1A输入低电平&#xff0c;L1B输入高电平 R1A输入低电平&#xff0c;R1B输入高电平 &a…

智能优化算法 | Matlab实现DBO蜣螂优化算法

智能优化算法 | Matlab实现DBO蜣螂优化算法 文章目录 智能优化算法 | Matlab实现DBO蜣螂优化算法文章概述源码设计文章概述 智能优化算法 | Matlab实现DBO蜣螂优化算法 源码设计 % ----------------------------------------------------------------------------------------…

(函数)判断一句话中最长的单词(C语言)

一、运行结果&#xff1b; 二、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h>//声明函数&#xff1b; int aiphabetic(char); int longest(char[]);int main() {//初始化变量值&#xff1b;int i;char line[100] { 0 };//获取用户输入字符…

【HM】使用@Builder装饰器,顺便要知道@BuilderParam,且注意this的指向

Builder装饰器修饰的函数是自定义构造函数&#xff0c;可以定义组件内构造函数&#xff0c;也可以定义全局构造函数&#xff0c;提供给外部组件使用。 就是通过自定义构造函数&#xff0c;可以把build(){// UI元素} 构造函数内的UI部分&#xff0c;抽离出来封装成一个函数&…

Gradle命令打包 Execution failed for task ‘:app:compileDebugJavaWithJavac错误

Gradle命令打包的时候遇到的&#xff0c;Gradle的java版本不对导致的&#xff0c;用的17&#xff0c;换成11的就能正常打包了。

大模型管理工具Ollama搭建及整合springboot

目录 一、Ollama介绍 1.1 什么是Ollama 1.2 Ollama特点与优势 二、Ollama本地部署 2.1 版本选择 2.2 下载安装包 2.3 执行安装 2.4 Ollama常用命令 三、使用Ollama部署千问大模型 3.1 千问大模型介绍 3.2 部署过程 四、springboot接入Ollama 4.1 引入Ollama依赖 4…

树莓派LCD显示屏安装驱动详细教程

使用LCD显示屏有两种方式&#xff0c;1.如果你已安装好树莓派官方系统&#xff0c;需要单独安装驱动才可点亮显示屏。 2. 也可以直接烧录我们提供的系统 里面已含驱动程序。 一&#xff1a;连接方式 按照下图方式连接好LCD显示屏与树莓派主板 二&#xff1a;安装系统镜像&…

6个适合在家做的副业兼职,做得好的月入过万,适合上班族和宝妈

嘿&#xff0c;亲爱的朋友们&#xff01;是不是常常觉得钱包瘪瘪&#xff0c;却又因为种种原因无法外出兼职&#xff1f; 别急&#xff0c;我来为大家揭秘几个在家也能轻松赚钱的靠谱副业&#xff0c;让你足不出户也能月入过万&#xff0c;从此告别财务烦恼&#xff01; 副业一…

7岁男孩学什么编程好一些:探索儿童编程的四大领域与未来潜能

7岁男孩学什么编程好一些&#xff1a;探索儿童编程的四大领域与未来潜能 在数字化时代&#xff0c;编程已成为一项重要的技能。对于7岁的男孩来说&#xff0c;选择适合的编程学习内容至关重要。那么&#xff0c;究竟哪些编程课程更适合这个年龄段的孩子呢&#xff1f;本文将从…

1.5.3 基于Java配置方式使用Spring MVC

本实战教程主要介绍了如何使用Java配置方式来使用Spring MVC框架。相较于XML配置方式&#xff0c;Java配置方式提供了一种更为简洁和灵活的配置方法。 项目创建与配置 创建一个Jakarta EE项目&#xff0c;并设置项目名称和位置。选择Jakarta EE 10版本&#xff0c;不添加依赖&a…

python中的预编译正则表达式

预编译正则表达式指的是使用Python的re模块中的re.compile()函数提前将正则表达式的字符串形式编译成一个正则表达式对象。这样&#xff0c;当你需要在多个地方或多次使用同一个正则表达式时&#xff0c;你可以重用这个编译后的对象&#xff0c;而不是在每次使用时重新编译表达…

404.左叶子之和

计算给定二叉树的所有左叶子之和。 示例&#xff1a; 思路&#xff1a; 通过父节点来判断七子节点是不是我们要收集的元素。因为如果遍历到孩子节点&#xff0c;我们无法判断它是左孩子还是右孩子。 后序遍历&#xff0c;左右中。 判断当前节点是不是左叶子是无法判断的&…

Turtle中circle用法详解

在Python的Turtle图形库中&#xff0c;circle方法是一个非常灵活的工具&#xff0c;它允许我们以简单的方式绘制圆或圆的一部分。本文将深入探讨circle方法&#xff0c;特别关注radius和extent参数的用途及其正负值的意义。 一、circle方法概览 首先&#xff0c;让我们了解一…

271 基于matlab的可调Q因子小波变换故障诊断

基于matlab的可调Q因子小波变换故障诊断&#xff0c;可用在轴承、齿轮、活塞等故障诊断中&#xff0c;程序中包含了原始TQWT工具箱和轴承振动信号信号的谱包络的求取。通过仿真数据、实际轴承数据说明了方法的效果。程序已调通&#xff0c;可直接运行。 271 可调Q因子小波变换 …

JavaScript第五讲:事件,条件循环语句,错误处理

前言 在编程的世界里&#xff0c;事件、条件和循环语句、以及错误处理是构建任何复杂程序或应用的基石。无论是开发一个简单的网页交互&#xff0c;还是构建一个庞大的企业级系统&#xff0c;这些基础概念都扮演着至关重要的角色。今天星途将通过这篇文章&#xff0c;分别深入…

java中判断String类型为空和null的方法

1.判断一个String类型的变量是否为空&#xff08;即长度为0&#xff09;或者为null 在Java中&#xff0c;判断一个String类型的变量是否为空&#xff08;即长度为0&#xff09;或者为null&#xff0c;通常需要使用两个条件语句来进行检查。这是因为null表示变量没有引用任何对…

01PCB设计概述

PCB设计概述 EDA electronic design automatic 电子设计自动化&#xff08;利用计算机来实现电子设计&#xff09; 分为 &#xff1a; 微电子&#xff08;芯片设计&#xff09;、硬件板卡&#xff08;PCB设计&#xff09; 画原理图、画PCB布线 要会绘制原理图库、和封装图库 元…

计算机组成原理06:浮点数运算

浮点数加减运算 之前我们提到过&#xff0c;浮点数具有特定的表示形式。因此&#xff0c;在进行浮点数的加减运算之前&#xff0c;需要统一浮点数的表达方式。这里我们主要对浮点数表示中的尾数M进行处理&#xff0c;要求0≤M<1&#xff0c;统一格式如下&#xff1a; 正数…

在Ubuntu下安装配置和调优iptables的终极指南

嘿&#xff0c;大家好&#xff01;今天我要和大家分享一篇关于在Ubuntu下安装配置和调优iptables防火墙的技术博客。废话不多说&#xff0c;我们直接切入主题。 首先&#xff0c;我要强调一下&#xff0c;今天我在阿贝云免费服务器上进行了部署测试。我得说&#xff0c;这个免…

LeetCode84:柱形图中最大的矩形

题目描述 给定 n 个非负整数&#xff0c;用来表示柱状图中各个柱子的高度。每个柱子彼此相邻&#xff0c;且宽度为 1 。 求在该柱状图中&#xff0c;能够勾勒出来的矩形的最大面积。 代码 单调栈 class Solution { public:int largestRectangleArea(vector<int>& h…