我可以从以前的参数中设置默认参数吗?

Posted

技术标签:

【中文标题】我可以从以前的参数中设置默认参数吗?【英文标题】:Can I set a default argument from a previous argument? 【发布时间】:2010-12-25 06:00:24 【问题描述】:

是否可以将函数参数列表中的先前参数用作参数列表中后续参数的默认值?例如,

void f( int a, int b = a, int c = b );

如果可以的话,有什么使用规则吗?

【问题讨论】:

【参考方案1】:

不,那不是合法的 C++。这在 C++ 标准的第 8.3.6/9 节中指定:

每个默认参数都被评估 调用函数的时间。这 函数参数的评估顺序 未指定。所以, 函数的参数不应 在默认参数表达式中使用, 即使它们没有被评估。

和:

int f(int a, int b = a); // 错误: 参数 a 用作默认参数

而且C89至少不支持默认参数值。

【讨论】:

【参考方案2】:

这是不可能的

【讨论】:

【参考方案3】:

不,你不能那样做。你肯定会得到一个错误“局部变量可能不会出现在这个上下文中”。

【讨论】:

【参考方案4】:

作为一种潜在的解决方法,您可以这样做:

const int defaultValue = -999; // or something similar

void f( int a, int b = defaultValue, int c = defaultValue )

    if (b == defaultValue)  b = a; 
    if (c == defaultValue)  c = b; 

    //...

【讨论】:

这将在运行时解析默认值。 Mike 的方法是在编译时解决的。此外,这假设类型(此处为 int)可能具有特殊的“默认”标志值(此处为 -999),并且您所做的事情是危险的:如果以某种方式将 -999 作为真实值传递,这将无法按预期工作。 ..【参考方案5】:

答案是否定的,你不能。您可以使用重载获得您想要的行为:

void f(int a, int b, int c);
inline void f(int a, int b)  f(a,b,b); 
inline void f(int a)         f(a,a,a); 

至于最后一个问题,C 根本不允许使用默认参数。

【讨论】:

为什么只内联其中的两个函数? @DavidDoria:我们不知道主重载是否可以或应该被内联——这超出了问题的范围。其他的只是简单地调用主重载,因此可以很容易地内联。 太糟糕了,我们不能用构造函数来做到这一点。我猜 C++20 已经指定了允许类似模式的初始化器。【参考方案6】:

我认为你不能这样做,因为这是一种非法的语法。但是,请参阅 pdf 格式 (n1136.pdf) 的 C99 标准。

但是,您可以通过使用 static 来解决这个问题,就像声明变量为静态并在函数 f 中使用它们一样

静态int global_a; /* 在你调用 f() 的其他地方,事先执行此操作 */ /* global_a = 4; F(); */ 无效 f(无效) int a = global_a; b = c = a; /* ..... */

感谢 Michael Burr 指出我的错误! :)

听起来你需要重新考虑你的代码并改变它。

【讨论】:

【参考方案7】:

你的第一个想法可能是做这样的事情:

void something(int a, int b=-1, int c=-1)
    if(b == -1)
        b = a;
    if(c == -1)
        c = b;

我使用 -1 因为这个函数只适用于正值。但是,如果有人使用我的类并犯了一个错误,最终将 -1 发​​送到该方法怎么办?它仍然会编译和执行,但结果对于用户来说是不可预知的。因此,明智的做法是删除任何默认参数,而是创建一堆具有相同名称的方法,如下所示:

void something(int a, int b, int c)
    /* Do something with a, b and c */


void something(int a)
    something(a, a, a);


void something(int a, int b)
    something(a, b, b);

编写代码实际上并不需要很长时间,如果有人在具有自动完成功能的编程界面中使用它,它将显示 3 种可能的原型。

【讨论】:

以上是关于我可以从以前的参数中设置默认参数吗?的主要内容,如果未能解决你的问题,请参考以下文章

在 Racket 中设置默认参数值

在 R 中设置函数参数的默认值

Golang中设置函数默认参数的优雅实现

在javascript中设置默认参数值的最有效方法是啥?

我用ABAP可以在SAP标准屏幕中设置默认值吗?比如

在 node.js 中的 HTTP GET 中设置 URL 参数的默认值