例如,像这样:
#include <cstdarg>
void my_function(int it=42, ...)
{
/* va_list/start/arg/end code here */
}
上述代码到底在C ++中意味着什么?它在G ++中编译得很好。请注意,我无法想象任何有用的情况,甚至它应该做的事情。我只是好奇。
答案 0 :(得分:6)
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
)?
在这种情况下,编译器也无法知道你的意图。
答案 1 :(得分:5)
是的,这个函数声明在技术上没有任何问题,虽然我不推荐这种做法,因为在调用函数时编译器无法提出错误会很容易出错。
您可以在第一个具有默认参数的参数处停止提供参数。如果你让默认参数接管,那么变量参数列表当然是空的。
您可以提供超出命名参数的参数,以便填充变量参数列表,在这种情况下,不会使用任何默认参数。
正如您所指出的,另一个问题是,实际情况是否真的有用。
答案 2 :(得分:0)
void my_function(int it=42, ...){ /* va_list/start/arg/end code here */}
那么代码应该完全按照它的样子行事。传递的拳头参数(如果有)是参数it
,其余参数是...
。因此,如果您没有传递任何参数,那么您的it
参数将被分配默认值(42),it
(等于42)是传递给函数的唯一参数。
这样的代码可能与...
的任何其他用法一样有用 - 在类似情况下终止的参数列表(并且风险具有相同的性质)。
示例:
您可以创建功能:
// 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;
}
Obvoiusly float_vector()
返回空向量,因为它与float_vector(0)
等价。在所有其他情况下,float_vector
的行为类似于具有可变数量参数的常规函数。