带有可变数量参数的函数,没有任何显式参数 [英] Function with a variable number of parameters without any explicit parameters
问题描述
如何在C ++中使用以下形式的函数: void function(...){}
?
确实至少需要一个隐式参数吗?
重复从一个评论:
看起来C99和C ++ 11在这里有一个有趣的区别:C ++ 11允许函数声明 void foo(...)
,因为 parameter-declaration-clause 中的 parameter-declaration-list 是可选的:[dcl.fct]
函数声明:
D1(
parameter-declaration-clausecv-qualifier-seq opt ref-qualifier < sub> opt 异常规范 opt 属性说明符seq opt
参数:
lockquote
参数声明子句:
parameter-declaration-list opt ...
opt
参数声明列表 ,...
< (请注意, parameter-declaration-list 和 ...
在这里分别是 opt ,意思是你可以省去一个或另一个或两者,这个解释是由clang ++和g ++支持的。)
在C99中,这个声明是不允许的,因为参数-list 在参数类型列表中不是可选的:6.7.5 / 1
$ b 函数声明:
直接声明符
(
parameter-type- list)
参数:
参数类型列表:
parameter-list
参数列表,...
作为 va_start
等。宏/函数是从C99继承的,因此无法使用与省略号匹配的参数和空的 parameter-declaration-list 在C ++中。
C99中的 va_start
7.15.1.4
void va_start(va_list ap,
parmN);
[...]
参数 parmN 是变量
参数列表中最右边参数的标识符(在,...
,之前)。 [...]
重点是我的。 C99 假定在省略号之前有一个参数,因为在C99中声明一个带省略号但不带参数的函数是不合法的。
然而,我可以看到有两个理由使用带省略号的函数,但没有C ++中的任何参数:
-
重载分辨率。将参数与省略号相匹配会导致重载排名非常低:省略号转换序列比任何用户定义的标准转换序列[over.ics.rank] / 2更差。这可以用于元编程:
char foo(int);
int foo(...);
struct S {};
S s;
sizeof(foo(42)); //产生1
sizeof(foo(s)); //产生sizeof(int)
How to work in C++ with functions the following form: void function(...) {}
?
Do really need at least one implicit parameter?
Repeating from a comment:
It seems there is an interesting difference between C99 and C++11 here: C++11 allows a function declaration void foo(...)
because the parameter-declaration-list in the parameter-declaration-clause is optional: [dcl.fct]
Function declaration:
D1 (
parameter-declaration-clause)
cv-qualifier-seqopt ref-qualifieropt exception-specificationopt attribute-specifier-seqopt
Parameters:
parameter-declaration-clause:
parameter-declaration-listopt...
opt
parameter-declaration-list, ...
(Note how both the parameter-declaration-list and the ...
are separately opt here, meaning you can leave out one or the other or both. This interpretation is supported by clang++ and g++.)
In C99, this declaration is not allowed since the parameter-list is not optional in the parameter-type-list: 6.7.5/1
Function declaration:
direct-declarator
(
parameter-type-list)
Parameters:
parameter-type-list:
parameter-list
parameter-list, ...
As the va_start
etc. macros/functions are inherited from C99, there's no way to use the arguments matched with the ellipsis with an empty parameter-declaration-list in C++.
Description of va_start
in C99: 7.15.1.4
void va_start(va_list ap,
parmN);
[...]
The parameter parmN is the identifier of the rightmost parameter in the variable parameter list in the function definition (the one just before the, ...
). [...]
Emphasis mine. C99 assumes there's a parameter before the ellipsis, because it isn't legal in C99 to declare a function with an ellipsis but without parameters.
Yet, I can see two reasons to use a function with an ellipsis but w/o any parameters in C++:
Overload resolution. Matching arguments to an ellipsis leads to a very low ranking of the overload: An ellipsis conversion sequence is worse than any user-defined and standard conversion sequence [over.ics.rank]/2. This can be useful for metaprogramming:
char foo(int); int foo(...); struct S{}; S s; sizeof(foo(42)); // yields 1 sizeof(foo(s)); // yields sizeof(int)
Implementation-defined tricks. Your implementation may provide a mean to access those arguments matched with an ellipsis. E.g. see BobTFish's example
这篇关于带有可变数量参数的函数,没有任何显式参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!