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

发布于 2024-11-04 06:21:50 字数 229 浏览 5 评论 0原文

例如,这样的事情:

#include <cstdarg>

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

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

For example, something like this:

#include <cstdarg>

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

What exactly does the above code mean in C++? It compiles fine in G++. Note, I can't imagine any scenario where this would be useful or even what it ought to do. I'm just curious.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

掀纱窥君容 2024-11-11 06:21:50
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 > 对于)?

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

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


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

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

那么这在 C++ 中一开始就是非法的。

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

f(9879, 97897, 7897);

最后一个参数 7897 是否对应于参数 p 或者它对应于可变参数(并且您打算使用 p 的默认值 10)?

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

void my_function(int it=42, ...)

You said this function compiles fine with GCC, but you cannot make use of the default argument, you will have to pass argument for the so-called default parameter as well, to work with this function.

my_function("string", 98, 78, 99); //error
my_function(898, "string", 98, 78, 99); //ok, but the param 'it' becomes 898

Ask yourself:

Is the first argument 898 corresponds to the parameter it or it corresponds to the variadic parameter (and you intend to use the default value 42 for it)?

The compiler cannot know your intention!

BTW @Johannes pointed out a good point : you can simply call my_function() without passing any argument. That is the only instance I see when you can make use of the default argument.


Now if you change the position of the default parameter, something like this:

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

Then this is illegal in C++ to begin with.

Again, ask yourself : if it was allowed then you could call this as:

f(9879, 97897, 7897);

Is the last argument 7897 corresponds to the parameter p or it corresponds to the variadic parameter (and you intend to use the default value 10 for p)?

The compiler cannot know your intention in this case either.

过度放纵 2024-11-11 06:21:50

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

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

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

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

Yes, there's nothing technically wrong with this function declaration, although I wouldn't recommend this practice because it would be very easy to make a mistake which the compiler couldn't warn about when calling the function.

You can stop providing arguments at the first argument that has a default argument. If you let the default arguments take over then the variable argument list will, of course, be empty.

You can provide arguments beyond the named parameters so populating the variable argument list in which case none of the default arguments will be used.

As you indicate, whether there's a practical situation where this would actual be useful is another question.

思慕 2024-11-11 06:21:50
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;
}

显然 float_vector() 返回空向量,因为它相当于 float_vector(0)。在所有其他情况下,float_vector 的行为类似于具有可变数量参数的普通函数。

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

Well that code ought to do exactly what it looks like. Fist parameter passed (if any) is parameter it and the rest is .... So if you pass no parameters then your it parameter is assigned default value (42) and it (that equals 42) is the only parameter passed into the function.

The code like this may be useful just like any other usage of ...-terminated argument-list in similar situations (and the risk is of the same nature).

Example:

You may create function:

// 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() returns empty vector because it is equvalent to float_vector(0). In all the other cases float_vector behaves like usual function with variable number of arguments.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文