2009-12-10 154 views
33

我无法找到明确的答案,虽然这可能是因为我没有使用正确的搜索条件,所以请重定向我,如果是这种情况。是否可以在函数参数列表中使用先前的参数作为参数列表中后面参数的默认值?例如,将C/C++默认参数设置为之前的参数

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

如果这是可能的,是否有任何使用规则? C和C++有什么不同?

+6

要回答你的问题的这部分,有** **没有在C – 2009-12-10 13:35:31

回答

52

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

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

你为什么直列只有两个功能是什么? – 2012-06-05 18:39:25

+5

@DavidDoria:我们已经不知道是否主要超载可以或应该被内联 - 这是超越了问题的范围。其他人简单地称为主要超载,因此可以轻松地内联。 – 2012-06-06 10:38:30

25

不,这不是合法的C++。这是在C++标准的部分8.3.6/9指定:

Default arguments are evaluated each time the function is called. The order of evaluation of function arguments is unspecified. Consequently, parameters of a function shall not be used in default argument expressions, even if they are not evaluated.

和:

int f(int a, int b = a); // error: parameter a used as default argument

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

3

这是不可能的

2

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

7

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

​​
+0

+1默认参数的概念是打算写这个问题,以及 – 2009-12-10 13:12:01

+0

谢谢。看看其他答案,我认为Mike Seymour的方法更好。 – 2009-12-10 13:13:46

+2

这将在运行时解析默认值。迈克的方法在编译时解决。此外,这假设类型(这里int)可能有一个特殊的“默认”标志值(这里是-999),并且你所做的事情是危险的:如果以某种方式将-999作为实际值传递,这将不会按预期工作。 .. – galinette 2014-05-06 16:06:24

1

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

但是,您可能会解决这个问题,通过使用static在声明变量静态和使用它们的函数中f

 
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; 
    /* ..... */ 
} 

荣誉迈克尔·伯尔指出我的错误! :)

这听起来像你需要重新考虑你的代码,并改变它的东西。

希望这会有所帮助, 最好的问候, 汤姆。

+0

我不跟随 - 如果你做这样的事,没有理由,因为在所有未被使用它们来传递参数。 – 2009-12-10 16:09:02

+0

@迈克尔伯尔:是的,你是正确的...我的坏!呃......我会相应地编辑它并提及你的意见。谢谢! :) – t0mm13b 2009-12-10 23:25:37

1

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

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种可能的原型。