Variadic arguments
变元
允许函数接受任意数量的参数。
由表单的参数表示...
的参数列表中必须最后出现的功能声明...
在语法上正确的地方,, ...
可代之以...
...
二次
// the function declared as follows
int printx(const char* fmt, ...
// may be called with one or more arguments:
printx("hello world"
printx("a=%d b=%d", a, b
int printx(const char* fmt... // same as above (comma is optional)
int printy(..., const char* fmt // error: ... must be the last
int printz(... // valid, but the arguments cannot be accessed portably
二次
注意:这与函数不同。参数包展开,它由参数声明器的一部分省略号表示,而不是以参数本身显示的省略号表示。参数包展开和省略参数都可能出现在函数模板的声明中,如std::is_function
...
默认转换
当调用变量函数时,在lvalue-to-rvalue、数组到指针和函数到指针之后。转换,作为变量参数列表一部分的每个参数都会经历称为默认参数提升
*
std::nullptr_t
转换为void*
float
参数转换为double
如浮点推广
bool
,,,char
,,,short
,并且非作用域枚举被转换为int
或更宽的整数类型,如整数提升
只允许算术、枚举、指针、指向成员的指针和类类型参数。
因为变量参数的秩最低,因此过载分辨率,它们通常用作SFINAE...
在使用各种参数的函数体中,可以使用<cstdarg>图书馆设施*
在标头中定义<cstdarg>
*。
Va[医]启动启用对变量函数参数%28的宏%29的访问
Va[医]arg访问下一个变量函数参数%28宏%29。
Va[医]复制%28C++11%29复制变量函数参数%28函数宏%29
Va[医]变量函数参数%28宏%29的末端遍历
Va[医]列表保存了va所需的信息。[医]开始,VA[医]阿格河[医]结束,和VA[医]拷贝%28---胡枝子
的行为va_start
如果省略号之前的最后一个参数具有引用类型,或者其类型与默认参数提升导致的类型不兼容,则未定义宏。
备选方案
- 可变模板也可用于创建接受可变参数数的函数。它们通常是更好的选择,因为它们不对参数的类型施加限制,不执行积分和浮点提升,并且类型安全。%28自C++11%29
- 如果所有变量参数共享公共类型,则
std::initializer_list
为访问变量参数提供方便的机制%28,尽管语法%29不同。%28自C++11%29
注记
在C编程语言中,至少一个命名参数必须出现在省略号参数之前,因此printz(...是无
效的。在C++中,即使传递给此类函数的参数不可访问,也允许使用此表单,并且通常用作SFINAE中省略号转换的最低优先级。过载分辨率...
这种变量参数的语法是在1987引入的,C++在省略号之前没有逗号。当C89采用C++的函数原型时,它将语法替换为需要逗号的语法。为了兼容,C++98同时接受C++样式。f(int n...)
和C型f(int n, ...)
...
另见
c变量参数的文档
*。
© cppreference.com
在CreativeCommonsAttribution下授权-ShareAlike未移植许可v3.0。