例如,像这样:
#include <cstdarg>
void my_function(int it=42, ...)
{
/* va_list/start/arg/end code here */
}
上面的代码在 C++ 中到底是什么意思?它在 G++ 中编译得很好。请注意,我无法想象在任何情况下这都会有用,甚至无法想象它应该做什么。我只是好奇。
例如,像这样:
#include <cstdarg>
void my_function(int it=42, ...)
{
/* va_list/start/arg/end code here */
}
上面的代码在 C++ 中到底是什么意思?它在 G++ 中编译得很好。请注意,我无法想象在任何情况下这都会有用,甚至无法想象它应该做什么。我只是好奇。
void my_function(int it=42, ...)
你说这个函数用 GCC 编译得很好,但是你不能使用默认参数,你还必须为所谓的默认参数传递参数,才能使用这个函数。
my_function("string", 98, 78, 99); //error
my_function(898, "string", 98, 78, 99); //ok, but the param 'it' becomes 898
问你自己:
第一个参数是898
对应于参数it
还是对应于可变参数(并且您打算使用默认值42
)it
?
编译器无法知道你的意图!
BTW @Johannes 指出了一个好点:您可以简单地调用my_function()
而不传递任何参数。这是我看到的唯一可以使用默认参数的实例。
现在,如果您更改默认参数的位置,如下所示:
void f(..., int p = 10); //illegal
那么这在 C++ 中是非法的。
再次问自己:如果允许,那么您可以将其称为:
f(9879, 97897, 7897);
最后一个参数是7897
对应于参数p
还是对应于可变参数(并且您打算使用默认值10
)p
?
在这种情况下,编译器也无法知道您的意图。
是的,这个函数声明在技术上没有任何问题,尽管我不推荐这种做法,因为很容易犯错误,编译器在调用函数时无法警告。
您可以在第一个具有默认参数的参数处停止提供参数。如果您让默认参数接管,那么变量参数列表当然将为空。
您可以提供命名参数之外的参数,以便填充变量参数列表,在这种情况下,将不使用任何默认参数。
正如您所指出的,是否存在实际有用的实际情况是另一个问题。
void my_function(int it=42, ...){ /* va_list/start/arg/end code here */}
那么该代码应该完全按照它的样子做。传递的第一个参数(如果有)是参数it
,其余的是...
. 因此,如果您不传递任何参数,那么您的it
参数将被分配默认值 (42),并且it
(等于 42)是传递给函数的唯一参数。
像在类似情况下使用 -terminated argument-list 的任何其他用法一样,这样的代码可能很有用...
(并且风险具有相同的性质)。
例子:
您可以创建功能:
// DECLARATION:
// returns vector filled with items specified
std::vector<float> float_vector( size_t item_count = 0, ... /* floats */ );
// DEFINITION:
std::vector<float> float_vector( size_t item_count, ... )
{
std::vector<float> vec;
va_list ap;
va_start(ap, item_count);
for( ; item_count > 0; --item_count )
{
vec.push_back( va_arg(ap,float) );
}
va_end(ap);
return vec;
}
显然float_vector()
返回空向量,因为它等同于float_vector(0)
. 在所有其他情况下,float_vector
其行为类似于具有可变数量参数的普通函数。