11

例如,像这样:

#include <cstdarg>

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

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

4

3 回答 3

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还是对应于可变参数(并且您打算使用默认值42it

编译器无法知道你的意图!

BTW @Johannes 指出了一个好点:您可以简单地调用my_function()而不传递任何参数。这是我看到的唯一可以使用默认参数的实例。


现在,如果您更改默认参数的位置,如下所示:

void f(..., int p = 10); //illegal

那么这在 C++ 中是非法的。

再次问自己:如果允许,那么您可以将其称为:

f(9879, 97897, 7897);

最后一个参数是7897对应于参数p还是对应于可变参数(并且您打算使用默认值10p

在这种情况下,编译器也无法知道您的意图。

于 2011-04-30T13:55:21.887 回答
5

是的,这个函数声明在技术上没有任何问题,尽管我不推荐这种做法,因为很容易犯错误,编译器在调用函数时无法警告。

您可以在第一个具有默认参数的参数处停止提供参数。如果您让默认参数接管,那么变量参数列表当然将为空。

您可以提供命名参数之外的参数,以便填充变量参数列表,在这种情况下,将不使用任何默认参数。

正如您所指出的,是否存在实际有用的实际情况是另一个问题。

于 2011-04-30T14:14:54.983 回答
0
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其行为类似于具有可变数量参数的普通函数。

于 2011-04-30T23:43:53.623 回答