我可以从上一个参数设置默认参数吗?

Can I set a default argument from a previous argument?

提问人:bpw1621 提问时间:12/10/2009 最后编辑:Baum mit Augenbpw1621 更新时间:5/2/2018 访问量:16504

问:

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

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

如果可能的话,是否有任何使用规则?

C++ 函数 参数

评论


答:

39赞 anon 12/10/2009 #1

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

默认参数将分别计算 调用函数的时间。这 函数参数的计算顺序 未指定。因此 函数的参数不得为 用于默认参数表达式, 即使它们没有被评估。

和:

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

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

3赞 Andreas Brinck 12/10/2009 #2

这是不可能的

3赞 Prasoon Saurav 12/10/2009 #3

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

7赞 e.James 12/10/2009 #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; }

    //...
}

评论

12赞 galinette 5/7/2014
这将在运行时解析默认值。Mike 的方法在编译时得到解决。此外,这假设类型(此处为 int)可能具有特殊的“默认”标志值(此处为 -999),并且您所做的是危险的:如果以某种方式将 -999 作为实际值传递,这将无法按预期工作......
88赞 Mike Seymour 12/10/2009 #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 根本不允许默认参数。

评论

1赞 David Doria 6/6/2012
为什么只内联了两个函数?
16赞 Mike Seymour 6/6/2012
@DavidDoria:我们不知道主重载是否可以或应该内联 - 这超出了问题的范围。其他人只是简单地调用主重载,因此可以很容易地内联。
0赞 wcochran 12/1/2021
太糟糕了,我们不能用构造函数来做到这一点。我猜 C++20 指定了允许类似模式的初始值设定项。
0赞 t0mm13b 12/10/2009 #6

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

但是,您可以通过使用 as 将变量声明为静态并在函数中使用它们来解决这个问题staticf

static int global_a;

/* In some other spot where you are calling f(), do this beforehand */
/* global_a = 4; f(); */

void f(void){
   int a = global_a;
   b = c = a;
   /* ..... */
}

感谢迈克尔·伯尔(Michael Burr)指出了我的错误!:)

听起来你需要重新考虑你的代码,并改变它来做这样的事情。

1赞 Domino 9/25/2013 #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 个可能的原型。