是否可以在单个函数中使用默认参数和可变数量的参数?

时间:2011-04-30 13:53:18

标签: c++ variadic-functions default-arguments

例如,像这样:

#include <cstdarg>

void my_function(int it=42, ...)
{
     /* va_list/start/arg/end code here */
}

上述代码到底在C ++中意味着什么?它在G ++中编译得很好。请注意,我无法想象任何有用的情况,甚至它应该做的事情。我只是好奇。

3 个答案:

答案 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的行为类似于具有可变数量参数的常规函数​​。